微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何知道无阻塞recv返回0时会发生哪种情况?

如何解决如何知道无阻塞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时会发生什么情况?

解决方法

recv返回0时,表示该套接字已被其他同位体正常关闭,并且也可以从您一侧关闭。如果套接字中没有数据,则返回-1并将errno设置为EAGAIN / ETIMEDOUT,并且套接字不必关闭。

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


正如您在上一次编辑中正确引用的那样,即使请求的大小为0,也可以从recv返回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 */
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。