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>