c - nonblocking recv返回0怎么知道是哪种情况?

标签 c sockets recv

我有一个使用非阻塞套接字运行的简单 TCP 服务器。

引用自 recv 的联机帮助页;

When a stream socket peer has performed an orderly shutdown, the return value will be 0 (the traditional "end-of-file" return).

The value 0 may also be returned if the requested number of bytes to receive from a stream socket was 0.

当套接字可读时,我用这段代码读取它:

uint8_t buf[2048];
ssize_t rlen;
while(1){
    rlen = recv(fd, buf, sizeof(buf), 0);
    if(rlen < 0){
        /* some error came, let's close socket... */
    }
    else if(rlen == 0){
        /* is there no bytes to read? do we need break; in here? */
        /* is socket closed by peer? do we need to close socket? */
    }
    /* some code that process buf and rlen... */
}

recv 返回 0 时,我们如何知道发生了哪种情况?

最佳答案

recv 返回 0 时,这意味着套接字已被其他对等点正常关闭,您也可以关闭它。当套接字中没有数据时,返回 -1 并且 errno设置为 EAGAIN/ETIMEDOUT 并且套接字尚未关闭。

最后,当返回 -1 并且 errno 设置为不同于 EWOULDBLOCKEAGAIN 的值时,必须关闭套接字,因为发生了一些不可恢复的错误。
对于非阻塞套接字,这意味着调用 recv 时没有数据立即可用。对于阻塞套接字),这意味着即使在先前使用 setsockopt() 设置的超时 (SO_RCVTIMEO) 过期后,也没有数据可用。


正如您在上次编辑中正确引用的那样,如果请求的大小为 0,也可以从 recv 返回 0。

How we can know which case happens when recv returns 0?

只需测试提供的 recv 大小(在本例中它是一个常量数组的大小,因此它没有多大意义;但如果它是来自其他地方的变量......):

bufSize = sizeof(buf);

/* further code that, who knows, might affect bufSize */

rlen = read(fd, buf, bufSize);
if(rlen < 0){
    if (errno != ETIMEDOUT && errno != EWOLUDBLOCK)
    {
        /* some error came, let's close socket... */
    }
}
else if(rlen == 0){
     if (bufSize != 0)
    {
        /* Close socket */
    }
}

关于c - nonblocking recv返回0怎么知道是哪种情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63533962/

相关文章:

c - C 中的硬链接(hard link)表

我可以在 UDP 套接字上将 SO_RCVBUF 设置为 1

ios - 我如何知道用户是否收到了 privatepub gem 发送的推送通知

android - UDP图像流Android

c - C : client not recieving 中的简单 TCP 客户端服务器模型

c - 处理坏文件描述符错误的方法

Python套接字接收 - 传入的数据包总是有不同的大小

c - 如何在 C 中创建一个数组数组?

c++ - 在 C 中使用 "extern"存储类说明符

c - Bash中的增减运算符是Undefined Behavior吗?