跳转至主要内容

下面的STCP代码片段展示了我观察到的一个问题。 它在调用recv时阻塞,直到有数据可读,然后它处理接收到的数据并再次调用recv,recv要么返回更多的数据(或错误),要么阻塞。 如果发生了错误,recv将返回一个-1,错误代码被设置在errno变量中。 你觉得这段代码还行吗?

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);
   }

该代码假设远程对等体永远不会优雅地关闭连接。 当远程对等体进行优雅关闭时,也就是调用关闭或关闭函数时,recv通过返回零字节来向本地应用程序表明这一点。 随后对recv的调用将继续返回零字节。 其结果是,现在的代码处于一个紧密的循环中,什么也不做。 例如

收到的字节数:8
收到的字节数:57
收到的字节数:16
收到的字节数:1
收到的字节数:1
收到的字节数:0
收到的字节数:0
收到的字节数:0
收到的字节数:0
收到的字节数:0
.. . . .

即使应用协议规定远程对等体永远不会优雅地关闭连接,你也不能保证连接永远不会被优雅地关闭。 远程应用程序可能有一个bug,或者远程TCP协议栈可能会在应用程序进程终止时进行优雅关闭。 也可能是其他应用程序建立了一个连接,然后在没有得到预期的响应时关闭了它。 安全审计(或恶意用户)进行端口扫描或banner抓取也可能会做一个优雅的关闭。 底线是,你总是要处理零字节的情况。

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);
   }

收到的字节数:28
收到的字节数:2
收到的字节数:58
挨近

 

© 2024Stratus Technologies.