当没有数据要读取时,读取套接字会给出 errno EAGAIN,而且如果我断开网络连接

Posted

技术标签:

【中文标题】当没有数据要读取时,读取套接字会给出 errno EAGAIN,而且如果我断开网络连接【英文标题】:Reading sockets gives errno EAGAIN when there is no data to read, but also if I disconnect network 【发布时间】:2012-04-26 09:48:45 【问题描述】:

如果可用,我正在调用读取函数来捕获接收到的数据包。当没有要获取的数据包时,我得到 errno EAGAIN,但是当网络断开时,我也得到 EAGAIN,所以我无法区分这两种情况。

    while ( ((n = read(sockfd, &(buffer[pos]), 1)) > 0) and not messageFound) 

            //reading byte by byte
            if (n == 1) 
               // Some stuff.. 
            
        

// Never returning 0, but when returning negative values:
        if (n < 0)
            qDebug()<< "Read error #" << errno << ": " << strerror(errno);
            if(errno != EAGAIN) // It is always this error, so it's never entering here
                qDebug()<< "Disconnected. Reason #" << errno << ": " << strerror(errno);
                *connected = false;
            
        

有什么方法可以检查套接字是否已断开连接,或者在调用 read 之前知道是否有可用的数据包? (我尝试使用 select 但似乎不起作用)

【问题讨论】:

请注意,调用 qDebug() 后的 errno 可能是也可能不是您所期望的。 【参考方案1】:

对于 POSIX 套接字,关闭连接和没有准备好数据的区别在于返回值。当连接关闭时,返回值为0,当没有数据时返回负值(见man page)

【讨论】:

很抱歉,但它不是那样工作的。如果我断开笔记本电脑与 WiFi 网络的连接,读取函数将返回一个负值,并且 EAGAIN 作为 errno。我需要一个不同的解决方案 好吧,我的错,我错过了与网络的断开连接。手册页上写着The return value will be 0 when the peer has performed an orderly shutdown.其实我知道拔掉网线在应用程序中是没有注意到的,但是我不知道断开WiFi网络的影响。 检测网络断开的最简单方法可能是使用 TCP KeepAlive,但这始终是检测延迟和可能的误报之间的权衡,请参阅tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO

以上是关于当没有数据要读取时,读取套接字会给出 errno EAGAIN,而且如果我断开网络连接的主要内容,如果未能解决你的问题,请参考以下文章

从套接字读取时出现意外行为

检测非阻塞套接字上的关闭连接

当目前没有 wsarecv 时,传入数据会发生啥

使用 `read` 和 `epoll` 异步读取套接字

c#SslStream的read()函数如何知道何时返回0?

Django:IOError [Errno 2] 使用 python 读取 JSON 文件路径时没有这样的文件或目录