kevent behavior with TCP socket
Denis Berezhnoy
denis.berezhnoy at gmail.com
Sat Aug 8 08:42:57 UTC 2009
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 at 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 at logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
>
>
> Best regards
>
> Denis
>
More information about the freebsd-net
mailing list