Sockets – socket programming-recv() function

csockets

i have a problem with recv() function in non-blocking socket (c language under unix)
i have set socket to be non-blocking with below code(server program):

int x;
x=fcntl(listen_sd,F_GETFL,0);
fcntl(listen_sd,F_SETFL,x | O_NONBLOCK);

when i call recv(), if message are available it returns the length of message,if not it blocks!!

i sued select function in my code too.

while(1)
       {
          /**********************************************/
          /* Receive data on this connection until the  */
          /* recv fails with EWOULDBLOCK.  If any other */
          /* failure occurs, we will close the          */
          /* connection.                                */
          /**********************************************/
          rc = recv(i, buffer, sizeof(buffer), 0);
          if (rc < 0)
          {
         if(errno == EAGAIN||errno == EWOULDBLOCK)
         {
        printf("no message\n");
        break;
         }

                perror(" recv() failed");
                close_conn = TRUE;

          }

          /**********************************************/
          /* Check to see if the connection has been    */
          /* closed by the client                       */
          /**********************************************/
          if (rc == 0)
          {
             printf("connection closed\n");
             close_conn = TRUE;
             break;


          }

          /**********************************************/
          /* Data was recevied                          */
          /**********************************************/
          len = rc;
          printf("  %d bytes received\n", len);
        }

if client send a message and doesn't close connection then server in first call of recv() gets message and in second call is blocked(in other words recv() doesn't return EWOULDBLOCK error at all!!)
why?

Best Answer

My guess is that you are putting the O_NONBLOCK call into the socket you use for listen. But once you have called accept you will get another socket that represents the connection. This new socket may or may not have the O_NONBLOCK inherited from the other one, depending on the platform.

Citing the man accept from my linux:

On Linux, the new socket returned by accept() does not inherit file status flags such as O_NONBLOCK and O_ASYNC from the listening socket. This behavior differs from the canonical BSD sockets implementation. Portable programs should not rely on inheritance or noninheritance of file status flags and always explicitly set all required flags on the socket returned from accept().

Related Topic