【问题标题】:Detect closed connection on non blocking socket检测非阻塞套接字上的关闭连接
【发布时间】:2015-07-20 05:51:02
【问题描述】:

如果我的问题重复,我真的很抱歉,但我没有在网站上找到有用的信息。

我正在使用非阻塞套接字和 select()。如何检测客户端是否关闭了非阻塞套接字上的连接?我看到当没有数据可供读取以及连接关闭时,read() 返回 -1 和 errno = EWOULDBLOCK。

如何区分上述情况?

【问题讨论】:

    标签: c sockets io


    【解决方案1】:

    当对端关闭连接时:

    1. select() 将返回可读的套接字。
    2. 套接字上的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 ...
    猜你喜欢
    • 2010-12-30
    • 2019-01-18
    • 1970-01-01
    • 2013-07-20
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多