linux 如何关闭非阻塞套接字?

eulz3vhy  于 2023-06-29  发布在  Linux
关注(0)|答案(3)|浏览(178)

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

vs91vp4v

vs91vp4v1#

重要的不是套接字的阻塞状态,而是SO_LINGER选项。getsockopt(2)
SO_LINGER控制未发送的消息在套接字上排队并执行close(2)时所采取的操作。如果套接字承诺可靠的数据传输,并且设置了SO_LINGER,系统将阻止close(2)尝试的进程,直到它能够传输数据或直到它决定无法传输信息(超时时间,称为延迟间隔,在SO_LINGER请求时,在setsockopt()系统调用中以秒为单位指定)。如果禁用SO_LINGER并发出close(2),系统将以允许该过程尽快继续的方式处理关闭。
也就是说,启用SO_LINGER后,TCP套接字上的close(2)错误将意味着内核无法在延迟间隔内传递数据(不包括其他错误,如无效的文件描述符等)。你永远不会知道。参见The ultimate SO_LINGER page, or why is my tcp not reliable

lfapxunr

lfapxunr2#

如果我们在非阻塞套接字上调用关闭系统调用,它将立即返回

  • socket* 始终关闭:* 连接 * 可能仍在向对等体写入。但你的问题包含了一个谬误:如果你在 any socket上调用close(),它会立即返回。关闭和写入套接字是异步的。你可以用SO_LINGER来控制它,尽管我怀疑它只适用于阻塞模式。如果需要的话,在用一个肯定的SO_LINGER关闭之前,也许你应该把套接字放回阻塞模式。
kxeu7u2r

kxeu7u2r3#

@user207421 -你的答案是错误的。如果套接字处于阻塞模式,并且TCP窗口已满/写缓冲区已满,则close()将阻塞,因为FIN数据包需要SEQ和ACK编号。在非阻塞套接字的情况下,您将获得EAGAIN。但是,如果启用了no-lending,close()将不发送FIN而是RST数据包,并且不使用SEQ/ACK。RST包将被立即发送,写缓冲区的内容将被简单地丢弃。SO_LINGER与阻塞或非阻塞modi没有任何关系。

相关问题