Skip to main content

The following STCP code fragment demonstrates a problem that I have observed.  It blocks on the recv call until there is data to read, then it processes the received data and calls recv again which will either return with more data (or an error) or block.  If an error has occurred, recv will return a -1 and the error code is set in the errno variable.  Does the code look OK to you?

while (1)
   {
   cBytes = recv (socks1, buffer, BUFFERLEN, 0);
   if (cBytes == -1)
      {
      perror ("Unexpected error at recv");
      exit (errno);
      }
   else
      printf ("number of bytes received : %dn", cBytes);
   }

The code assumes that the remote peer will never gracefully close the connection.  When the remote peer does a graceful close, that is it calls the close or shutdown function, recv indicates this to the local application by returning zero bytes.  Subsequent calls to recv will continue to return zero bytes.  The result is that the code is now in a tight loop doing nothing.  For example

number of bytes received : 8
number of bytes received : 57
number of bytes received : 16
number of bytes received : 1
number of bytes received : 1
number of bytes received : 0
number of bytes received : 0
number of bytes received : 0
number of bytes received : 0
number of bytes received : 0
. . . . .

Even if the application protocol dictates that the remote peer will never gracefully close the connection, you cannot guarantee that the connection will never be gracefully closed.  The remote application can have a bug or the remote TCP stack may do a graceful close when the application process terminates.  Or perhaps some other application made a connection and then closed it when it didn’t get the response it expected.  A security audit (or a malicious user) doing a port scan or banner grabbing may also do a graceful close.  The bottom line is that you always have to handle the case of zero bytes.

while (1)
   {
   cBytes = recv (socks1, buffer, BUFFERLEN, 0);
   if (cBytes <= 0)
      {
      if (cBytes < 0)
         {
         perror ("Unexpected error at recv");
         exit (errno);
         }
      else
         {
         printf ("received closen");
         close (socks1);
         exit (0);
         }
      }
   else
      printf ("number of bytes received : %dn", cBytes);
   }

number of bytes received : 28
number of bytes received : 2
number of bytes received : 58
received close

 

© 2024 Stratus Technologies.