c - 如何知道非阻塞recv返回0时会发生哪种情况?
问题描述
我有一个使用非阻塞套接字运行的简单 TCP 服务器。
引用来自 recv 的联机帮助页;
当流套接字对等点执行了有序关闭时,返回值将为 0(传统的“文件结束”返回)。
如果从流套接字接收的请求字节数为 0,则也可能返回值 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 时会发生哪种情况?
解决方案
返回 0时recv
,表示套接字已被其他对等方优雅地关闭,并且也可以从您这边关闭。当套接字中没有数据时,返回 -1 并errno
设置为EAGAIN
/ETIMEDOUT
并且套接字尚未关闭。
最后,当返回 -1 并errno
设置为不同的值EWOULDBLOCK
或EAGAIN
必须关闭套接字时,因为发生了一些不可恢复的错误。
对于非阻塞套接字,这意味着recv
调用时没有立即可用的数据。对于阻塞套接字)这意味着 tgat 没有数据可用,即使在SO_RCVTIMEO
之前设置的超时()setsockopt()
过期后也是如此。
正如您在上次编辑中正确引用的那样,recv
如果请求的大小为 0,则也可以返回 0。
我们如何知道当 recv 返回 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 */
}
}
推荐阅读
- concourse - 如何从另一个资源的目录执行 Concourse 任务脚本?
- reactjs - 如何从地图功能中仅选择一个元素?
- java - Azure 存储 blob 客户端加密不解密 Java
- c - 如何不使指向数组 [0] 的指针在每个周期修改数组 [0]
- c++ - 我可以使用 stb_image_write.h 将 JPG 图像写入内存吗?
- kotlin - Kotlin 继承问题 - 固有的类类型转换
- c++ - 我在 c++ 中的 AES 代码有问题。明文在变化,但加密的消息是一样的。我找不到我的错误
- laravel - 在虚拟主机中的 nginx.conf 中安装 laravel 错误
- php - 按月显示事件 (cpt)
- javascript - React 表排序不一致,它不断变回默认状态