kevent behavior with TCP socket

den_b

New Member


Messages: 2

Hi guys,

I have a 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
 
OP
OP
D

den_b

New Member


Messages: 2

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:

Code:
#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
Code:
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
 
Top