我知道,在这里,在SO,有很多这样的主题问题。我已经通读了大部分类似的问题,却找不到适合我的答案。
我使用kqueue
服务器/客户端套接字echo应用程序。该程序专门使用BSD套接字API。该计划正在进行中。现在我正在从套接字获得EOF
。
我的设置如下。
- 启动服务器,等待连接,并接受一个套接字
- 启动连接的客户端
- 此时没有发送用户数据。使用
SIGINT
关闭客户端 - 服务器
kqueue
获得EOF
标志,没有错误 read
系统调用返回zero
,没有错误。
问题是我没有得到连接完全关闭的指示。我不能确定我是否必须shutdown
读结束,或完全关闭一个套接字。我在写端没有得到EOF
的指示。这是预料之中的,因为我没有注册写事件(到现在还没有发送数据)。
如何正确判断插座是否完全关闭?
我知道下面的内容可能属于其他帖子。我认为这个更新是与问题紧密相连的,问题将作为一个整体受益。
说到点子上。因为我得到一个读EOF
,但不是一个写EOF
(套接字在任何数据进入或输出之前关闭),我能以某种方式查询套接字的状态吗?
我从其他网络相关问题中学到的,这里,在SO上,网络堆栈可能会在套接字上获得一些数据包。比如FIN
或RST
。在特定的情况下,只获取套接字状态对我来说是一个肯定的胜利。
作为第二个选项,在之后添加一次性写事件是否有帮助?我有一个读EOF
,只是为了写EOF
?写EOF
事件会触发吗?
我知道我最终会得到写错误。但是,在此之前,套接字将是一个累赘。
对于getsockopt
的写结束关闭将是非常方便的。或者,至少在读取返回EOF
之后,排队等待读取端点关闭事件。
我没有找到类似的getsockopt
选项,我不确定队列写事件。kevent
的源代码,以及一般的网络堆栈,对我来说太难了。这就是为什么我问。
如果read
或recv
返回0
,则表示另一端关闭了连接。对于写入(来自另一个对等端)来说,它至少是一半关闭的,这意味着没有更多的东西可以从该连接接收。
除非协议指定它只是半关闭,并且您可以继续发送数据,否则通常最好从您的端简单地完全关闭连接。