Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Aug 2009 13:38:22 +0200
From:      Adrian Penisoara <ady@freebsd.ady.ro>
To:        Denis Berezhnoy <denis.berezhnoy@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: kevent behavior with TCP socket
Message-ID:  <78cb3d3f0908090438n63eefbb2t462385e8fcfb2395@mail.gmail.com>
In-Reply-To: <18b5e36e0908080142o5914903n335ebae17e82e985@mail.gmail.com>
References:  <18b5e36e0908060115g76a56da3qb23fdd208e7c4a4c@mail.gmail.com> <18b5e36e0908080142o5914903n335ebae17e82e985@mail.gmail.com>

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

On Sat, Aug 8, 2009 at 10:42 AM, Denis Berezhnoy
<denis.berezhnoy@gmail.com>wrote:

> 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.
>

  Question: is there something listening on your loopback address
(127.0.0.1) or all addresses at port 10000 (sockstat -4 output should be
evident) ? If not, have you also tested with something listening on that
address ?

  If there is nothing to connect onto the loopback address then the
connection will immediately fail. Then I believe kevent should return with a
failure filter flag set.

  One problem I see is that you are checking the action flags (kevent.flags)
instead of the filter flags (kevent.fflags). Please re-run checking the
sEvent.fflags field and compare with values in <sys/event.h> and let us/me
know what do you get.

Regards,
Adrian Penisoara
EnterpriseBSD



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