重要的不是套接字的阻塞状态,而是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。
3条答案
按热度按时间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。lfapxunr2#
如果我们在非阻塞套接字上调用关闭系统调用,它将立即返回
kxeu7u2r3#
@user207421 -你的答案是错误的。如果套接字处于阻塞模式,并且TCP窗口已满/写缓冲区已满,则close()将阻塞,因为FIN数据包需要SEQ和ACK编号。在非阻塞套接字的情况下,您将获得EAGAIN。但是,如果启用了no-lending,close()将不发送FIN而是RST数据包,并且不使用SEQ/ACK。RST包将被立即发送,写缓冲区的内容将被简单地丢弃。SO_LINGER与阻塞或非阻塞modi没有任何关系。