检测非阻塞套接字上的关闭连接
Posted
技术标签:
【中文标题】检测非阻塞套接字上的关闭连接【英文标题】:Detect closed connection on non blocking socket 【发布时间】:2015-07-20 05:51:02 【问题描述】:如果我的问题重复,我真的很抱歉,但我没有在网站上找到有用的信息。
我正在使用非阻塞套接字和 select()。如何检测客户端是否关闭了非阻塞套接字上的连接?我看到当没有数据可供读取以及连接关闭时,read() 返回 -1 和 errno = EWOULDBLOCK。
如何区分上述情况?
【问题讨论】:
【参考方案1】:当对端关闭连接时:
select()
将返回可读的套接字。
套接字上的recv()
或read()
将返回零。
当没有数据可供读取时,我看到 read() 返回 -1 且 errno = EWOULDBLOCK
正确,但连接没有关闭。
以及连接关闭时。
不,你没有。这是不正确的。它返回零。
如何区分上述情况?
它们不一样,它们的表现方式也不相同。
【讨论】:
你是对的!我刚刚制作了一个玩具客户端 - 服务器应用程序,它按照你和我的解释工作。在我的原始应用程序中,我从浏览器收集连接,并且我看到创建了一个线程来从服务器获取每个图像。线程获取图像时是否有可能不关闭套接字/连接? 是的,这就是 HTTP keep-alive 的效果。但是,如果您正在发送,则无需担心接收时会发生什么。发送图片后关闭套接字即可。 不,我的应用程序位于服务器端和客户端之间。它就像一个转发器,也就是说,它必须收集从一侧到达的数据,然后将它们转发到另一侧。我的转发器应用程序应该能够检测到客户端何时关闭连接,因为我需要关闭无用的套接字和无用的线程(我的意思是,完成工作的线程)。那么,如果我使用 HTTP keep-alive,有没有办法检测到线程工作的结束? 解决方案:在长连接中,经过一定时间后,read()返回0,所以可以检测到关闭的连接。 @LucaForte '经过一段时间' 与它无关。当对等方关闭连接时,read()
返回零,这可能是在一秒钟、一年或一个世纪之后。【参考方案2】:
当对等端关闭特定套接字的连接时,在此套接字上调用read()
将返回0
。此行为与套接字的阻塞状态无关。
来自man 2 read
(我的斜体):
返回值
成功时,返回读取的字节数(零表示文件结束)
【讨论】:
Any 调用返回零。如果第一次调用返回零,则表明对等端关闭而不发送任何内容的非常不寻常的情况。一旦返回零,它将继续返回。 删除了三振。没有人关心之前的错误,如果他们这样做了,它们就会出现在编辑历史记录中。 @EJP:谢谢,我只是把它留在里面以避免悬空的评论。 :-) 所以让我们清理 cmets ...以上是关于检测非阻塞套接字上的关闭连接的主要内容,如果未能解决你的问题,请参考以下文章