Home > Software design >  c: accept() for non-blocking server
c: accept() for non-blocking server

Time:07-26

I am writing a tcp server interface in C. In this interface, I would require to listen for command and send periodic outputs through the same sockets. I would think in this case I would need to program my sockets to be non-blocking. Here is my code

#define ERROR         -1
#define MAX_CLIENTS    2
#define MAX_DATA    1024

int setNonblocking(int fd)
{
    int flags;

#if defined(O_NONBLOCK)
    if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
        flags = 0;
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
    flags = 1;
    return ioctl(fd, FIOBIO, &flags);
#endif
} 

int main()
{
    int       lsock;                           
    struct    sockaddr_in saddr;  
    short int port;       
    char      buffer[MAX_DATA];
  
    int socketOption=1;
    int LISTENQ     =1;

    /// creating sockets
    if ( (lsock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
       printf(" Error: sockets creation \n");
       return -1;
    }

    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family      = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port        = htons(2222);

    setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &socketOption, sizeof(socketOption));

    setNonblocking(lsock);

    if ( bind(lsock, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) < 0 )
    {
        fprintf(stderr, "ECHOSERV: Error calling bind()\n");
        return -1;
    }

    if ( listen(lsock, LISTENQ) < 0 )
    {
        fprintf(stderr, "ECHOSERV: Error calling listen()\n");
        return -1;
     }

    bool running    = true;
    bool bConnected = true;
    while ( running )
    {
        int       csock; 
        time_t start = time(NULL);
        time_t now;             
        if ( (csock = accept(lsock, NULL, NULL) ) < 0 )
        {
            int errno_s = errno;
            printf("The error is %d \n", errno_s);
            fprintf(stderr, "ECHOSERV: Error calling accept()\n");
            return -1;
        } 
        else
        {
            bConnected  =true;
        }

        while(bConnected)
        {
           int n;
           if((n=recv(lsock, buffer, MAX_DATA, 0)) > 0)
           {
               printf("Command Handling \n");
           }

           if(now - start == 100)
           {
               printf("Data Sending \n");
           }

        }
    return 0;
}

The program always run into error whenever accept() is being called, I wonder why csock always return -1? I then tried to print out the errno. The errno read 11, which seems to be EAGAIN ( telling to try again ). So should I ignore this error?

I did think about other method to achieve what I want eg using select() and a set of file sockets... but somehow i think it might run into problem

Need your opinion and help on this

REgards

CodePudding user response:

See the accept man page:

If no pending connections are present on the queue, and the socket is not marked as nonblocking, accept() blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue, accept() fails with the error EAGAIN or EWOULDBLOCK.

You can use select() to test for data on a listening socket, and then call accept() only when it actually has data, ie a pending connection.

  • Related