如何关闭非阻塞套接字?

发布于 2024-11-16 03:36:19 字数 93 浏览 2 评论 0原文

我相信,如果我们在非阻塞套接字上调用 close 系统调用,它会立即返回,那么如何处理响应?是否关闭? 换句话说,套接字系统调用 close 在非阻塞套接字上的行为是什么?

I believe that if we call close system call on a non-blocking socket it returns immediately, then how to handle the response? whether it is closed or not?
in other words what is the behavior of the socket system call close on a non-blocking socket?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

躲猫猫 2024-11-23 03:36:19

重要的不是套接字的阻塞状态,而是 SO_LINGER 选项。来自 getsockopt(2)

SO_LINGER 控制未发送消息排队时采取的操作
套接字并执行 close(2)。如果套接字承诺可靠
发送数据并设置SO_LINGER,系统将阻塞该进程
close(2) 尝试中,直到能够传输数据或直到
决定无法传递信息(超时期限,称为
延迟间隔,在 setsockopt() 系统中以秒为单位指定
当请求 SO_LINGER 时调用)。如果 SO_LINGER 被禁用并且
发出 close(2) 后,系统将按照以下方式处理关闭:
允许该过程尽快继续。

也就是说,在 SO_LINGER 启用的情况下,TCP 套接字上来自 close(2) 的错误将意味着内核无法在延迟间隔内传送数据(不包括其他错误,例如无效错误)文件描述符等)。挥之不去的残疾 - 你永远不知道。另请参阅 最终的SO_LINGER页面,或者为什么我的tcp不可靠

It's not the blocking state of the socket, it's the SO_LINGER option that matters. From getsockopt(2):

SO_LINGER controls the action taken when unsent messages are queued on
socket and a close(2) is performed. If the socket promises reliable
delivery of data and SO_LINGER is set, the system will block the process
on the close(2) attempt until it is able to transmit the data or until it
decides it is unable to deliver the information (a timeout period, termed
the linger interval, is specified in seconds in the setsockopt() system
call when SO_LINGER is requested). If SO_LINGER is disabled and a
close(2) is issued, the system will process the close in a manner that
allows the process to continue as quickly as possible.

That is, with SO_LINGER enabled an error from close(2) on TCP socket would mean that kernel was not able to deliver data within linger interval (not counting other errors like invalid file descriptor, etc.). With lingering disabled - you never know. Also see The ultimate SO_LINGER page, or why is my tcp not reliable.

☆獨立☆ 2024-11-23 03:36:19

如果我们调用 close 系统调用
它返回的非阻塞套接字
立即

套接字始终关闭:连接可能仍在向对等方写入数据。但你的问题体现了一个谬误:如果你在任何套接字上调用 close() ,它都会立即返回。关闭和写入套接字是异步的。您可以按照其他答案使用 SO_LINGER 进行控制,尽管我怀疑这只适用于阻塞模式。如果您需要这样做,您可能应该在使用正 SO_LINGER 关闭之前将套接字重新置于阻塞模式。

if we call close system call on a
non-blocking socket it returns
immediately

The socket is always closed: the connection may still be writing to the peer. But your question embodies a fallacy: if you call close() on any socket it will return immediately. Closing and writing to a socket is asynchronous. You can control that with SO_LINGER as per the other answer, although I suspect that only applies to blocking mode. Probably you should put the socket back into blocking mode before closing with a positive SO_LINGER if that's what you need to do.

简单爱 2024-11-23 03:36:19

@user207421 - 你的答案是错误的。如果套接字处于阻塞模式,并且 TCP 窗口已满/写入缓冲区已满,则 close() 将阻塞,因为 FIN 数据包需要 SEQ 和 ACK 编号。如果是非阻塞套接字,您会得到 EAGAIN。
然而,当 no-lingering 打开时,close() 将发送 RST 数据包而不是 FIN,并且不使用 SEQ/ACK。 RST 数据包将立即发送,写缓冲区的内容将被简单丢弃。 SO_LINGER 与阻塞或非阻塞 modi 没有任何关系——实际上没有任何关系。

@user207421 - your answer is wrong. If the socket is in blocking mode, and the TCP window is full/the write buffer is full, close() WILL block because the FIN packet requires SEQ and ACK numbers. In case of a non blocking socket, you get EAGAIN.
However, with no-lingering turned on, close() will send not a FIN but RST packet and it does not use SEQ/ACK. RST packet will be sent immediately, and the contents of write buffer will be simply discarded. SO_LINGER has nothing - really nothing - to do with blocking or non-blocking modi.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文