dmo*_*221 5 c sockets recv server
我在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
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题:recv()由于网络问题而没有客户端执行有序关闭,是否有可能返回0个字节,从而导致我的代码过早地退出循环?手册页含糊不清.
TL; DR:POSIX说"不".
我不认为手册页不是那么清楚,但POSIX的描述可能更清楚一点:
该
recv()函数应从连接模式或无连接模式套接字接收消息.[...]
成功完成后,
recv()应以字节为单位返回消息的长度.如果没有可用的消息接收并且对等体已经执行了有序关闭,recv()则应返回0.否则,应返回-1并errno设置为指示错误.
因此,POSIX正好有三种选择:
recv()成功接收消息并返回其长度.根据定义,长度是非零的,因为如果没有收到字节,则没有收到消息.recv()因此返回大于0的值.
没有收到来自对等方的消息,我们相信没有任何消息即将发布,因为对等方已经(在recv()返回时)执行了有序的连接关闭.recv()返回0.
"否则"发生了其他事情.recv()返回-1.
在任何情况下,recv()如果没有可用数据且套接字上没有错误条件,则将阻塞,除非套接字处于非阻塞模式.在非阻塞模式下,如果在recv()调用时既没有数据也没有错误条件,则属于"其他"情况.
人们不能完全排除给定系统不符合POSIX,但你必须以某种方式决定你将如何解释功能结果.如果您在声称符合POSIX的系统上调用POSIX定义的函数(至少就该函数而言),则很难依赖于POSIX语义.
| 归档时间: |
|
| 查看次数: |
4602 次 |
| 最近记录: |