Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Aug 2009 17:42:56 +0900
From:      Denis Berezhnoy <denis.berezhnoy@gmail.com>
To:        freebsd-net@freebsd.org
Subject:   Re: kevent behavior with TCP socket
Message-ID:  <18b5e36e0908080142o5914903n335ebae17e82e985@mail.gmail.com>
In-Reply-To: <18b5e36e0908060115g76a56da3qb23fdd208e7c4a4c@mail.gmail.com>
References:  <18b5e36e0908060115g76a56da3qb23fdd208e7c4a4c@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

Sorry for my previous post it was completely unclear I believe. Here is
problem description in pure C. Can you please take a look at the code
below:

#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <errno.h>



int main(int argc, char *argv[])
{
struct sockaddr_in addr;
struct sockaddr_in addr2;

int sd, cd, port, sRet;

int sHandle;
int sEventNum = 0;

struct kevent sChange;
struct kevent sEvent;

struct timespec *sTimeoutPtr;
struct timespec sTimeout;

struct timeval sTimeVal1 = {0,0};
struct timeval sTimeVal2 = {0,0};

printf("Socket test start\n");

sd = socket(PF_INET, SOCK_STREAM, 0);

if ( sd < 0 )
{
printf("Server socket error\n");
return 0;
}

port = htons(10000);


memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = htonl(INADDR_ANY);

if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )

{
printf ("Server bind errror\n");
return 0;
}



if ( listen(sd, 1) != 0 )
{
printf ("Server listen error \n");
return 0;
}


cd = socket(PF_INET, SOCK_STREAM, 0);

if ( cd < 0 )
{
printf("Client socket error\n");
return 0;
}

sRet = fcntl(cd, F_GETFL, 0);

sRet |= O_NONBLOCK;

sRet = fcntl(cd, F_SETFL, sRet);

if (sRet < 0)
{
printf("can not set non block\n");
}

port = htons(10000);

memset(&addr2, 0, sizeof(addr2)); /* Clear struct */
addr2.sin_family = AF_INET; /* Internet/IP */
addr2.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* IP address */
addr2.sin_port = port; /* server port */

/* Establish connection */

if ((sRet = connect(cd,
(struct sockaddr *) &addr2,
sizeof(addr2))) < 0)
{

printf("Failed to connect with server %d\n", errno);

}


sHandle = kqueue();


if (sHandle == -1)
{
printf("Poll can not created queue\n");
}

sTimeout.tv_sec = 0;
sTimeout.tv_nsec = 100000000;;

EV_SET(&sChange, cd, EVFILT_WRITE, EV_ADD,0, 0, 0);


gettimeofday(&sTimeVal1, NULL);

sEventNum = kevent(sHandle,
&sChange,
1,
&sEvent,
1,
&sTimeout);

gettimeofday(&sTimeVal2, NULL);

printf ("Kevent event num %d wait time %d \n", sEventNum, sTimeVal2.tv_usec
- sTimeVal1.tv_usec);

if (sEventNum == 1)
{
printf ("Event filter %d flag %d data %d \n", sEvent.filter, sEvent.flags,
sEvent.data);
}

close(sHandle);

close(cd);

close(sd);

printf("Socket test end\n");
}

Program output

Socket test start
Failed to connect with server 36
Kevent event num 1 wait time 26
Event filter -2 flag 0 data 43008
Socket test end

The question is why kevent returns 1 event when server does not accept
connections from clients.

Best regards,
Denis

2009/8/6 Denis Berezhnoy <denis.berezhnoy@gmail.com>

> Hi guys,
>
>
> I have question regarding kevent behavior with TCP socket.  Hope you can
> advise anything.
>
>
> I am trying to connect the server in non block mode. When I call connect it
> returns -1 and errno=EINPROGRESS. Then I use kqueue and kevent with
> EVFILT_WRITE and timeout 100 msec to wait when server will be available to
> accept connection.
>
>
> kevent returns me 1 event without any timeout (filters = -2 (EVFILT_WRITE)
> flags = 0 data = 43008)
>
>
>
> So I consider this as server is ready to accept connection but when I check
> socket error after kevent returns by
>
> getsockopt with SOL_SOCKET and SO_ERROR params it returns me socket error
> 54  ECONNRESET /* Connection reset by peer */
>
> and no connection can be established using this socket.
>
>
> I am confused why kevent returns event that seems to indicate good
> condition  but actual socket status indicates error. What I am doing wrong?
>
>
> Sorry for this rough description of the problem my code is the part of
> large system so I can not simply copy paste code.
>
>
> I am using:
>
>
> FreeBSD freebsd 7.1-RELEASE FreeBSD 7.1-RELEASE #0: Thu Jan  1 14:37:25 UTC
> 2009     root@logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>
>
> Best regards
>
> Denis
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?18b5e36e0908080142o5914903n335ebae17e82e985>