recv(...)是这样运作的吗?

时间:2013-12-16 18:32:50

标签: c sockets posix recv

我使用SO_RCVTIMEO为套接字设置超时为10秒。此问题特定于流套接字(TCP)。当我从手册页中收集recv(...)时,这就是我所期待的:

  1. 如果远程关闭连接,则无论超时如何,它都会立即返回0。
  2. 如果超时到期且未收到任何数据,则返回-1并errno EAGAINEWOULDBLOCK
  3. 如果套接字上发生错误,则会立即返回-1,然后errno设置正确。
  4. 如果数据可用,套接字将等待,直到超时发生,然后才返回。这次它将在10秒内返回,并收到总字节数。
  5. 这是正确的行为吗?我只是想确保我正确理解文档。

    谢谢! 布雷特

2 个答案:

答案 0 :(得分:6)

  1. 正确。
  2. 有两种不同的规格(遗憾的是我目前无法测试)
    2.1 ETIMEOUT将被退回。如果没有数据立即可用,则会在非阻塞套接字上返回EAGAINEWOULDBLOCK。)http://pubs.opengroup.org/onlinepubs/9699919799/functions/recv.html
    对于2.1 http://man7.org/linux/man-pages/man2/recvmsg.2.html
  3. 中提到的两种可能性,将返回EAGAINEWOULDBLOCK
  4. 正确。
  5. 如果读取了至少1个字节,套接字可能会随时返回,即使读取的内容少,然后告知超时还没有到期。

答案 1 :(得分:0)

非常。

有一点需要注意:如果你设置MSG_WAITALL,每次有些数据到达时,至少有一个实现(FreeBSD)会重新启动计时器。例如,如果您要求recv 8192个字节并且一个字节到达,the timer is reset。如果另一个字节在10秒内到达,则计时器再次重置。因此,如果字节每5秒钟一次涓流,你将等待(8191 * 5)= 40955秒=超过11小时recv最终返回8192.(如果没有足够的字节到达EOF之前recv失败了EAGAIN。)

文档暗示(至少对我来说)即使没有MSG_WAITALL也是如此,但测试表明此警告仅适用于MSG_WAITALL案例。