【发布时间】:2016-10-27 13:27:49
【问题描述】:
我已经用 C 语言实现了一个 Web 服务器。它在已连接的阻塞套接字上调用 recv() 以接收传入的 HTTP 请求。 Linux 手册页对阻塞套接字上的 recv() 进行了以下说明:
如果套接字上没有可用的消息,则接收调用会等待消息到达...接收调用通常会返回任何可用数据,直到请求的数量,而不是等待接收请求的全部数量。
...
这些调用返回接收到的字节数,如果发生错误,则返回 -1...当对等方执行有序关闭时,返回值为 0。
因此,为了接收完整的请求,我的服务器代码包含以下形式的循环:
int connfd; // accepted connection
int len; // # of received bytes on each recv call
...
while (/* HTTP message received so far has not terminated */) {
len = recv(connfd, ...);
if (len == 0) {
// close connfd, then escape loop
} else if (len < 0) {
// handle error
} else {
// process received bytes
}
}
我的问题:recv() 是否有可能由于网络问题而返回 0 字节并且客户端没有执行有序关闭,从而导致我的代码过早退出循环?手册页含糊不清。
【问题讨论】:
-
这是一个“可以”还是“我该怎么做”的问题?也就是说,您是希望能够接收零字节还是只想知道它是否会发生?
-
@Clifford 只是一个“可以”的问题
-
好的。尽管接受和投票赞成的答案强调“否”,但答案显然是“是”,尽管在标题和正文之间,您的问题似乎将 receiving 零字节与 返回值为零;它们并不完全相同。也就是返回值>0时只代表接收到的字节数。
-
@Clifford 你说得对,我的问题措辞含糊不清。我很抱歉。更准确地说,我的问题是 recv() 是否有可能返回值 0 以指示它已从客户端接收到 0 个字节但客户端没有执行关闭。正如我在对约翰回答的评论中解释的那样,造成这种混乱的原因是对“消息”概念的误解。
-
对于我更精确措辞的问题,观察到的行为只是返回 value 0,我相信 John 的答案是正确的。