【发布时间】:2012-02-11 00:58:35
【问题描述】:
在最后一个send() 之后直接close() 一个套接字是否明智/安全?
我知道即使在关闭套接字之后,TCP 也应该尝试传递发送缓冲区中的所有剩余数据,但我真的可以指望吗?
我正在确保我的接收缓冲区中没有剩余数据,以便在我关闭后不会发送 RST。
就我而言,close 实际上是调用exit() 之前的最后一条代码语句。
即使在发送数据的进程终止后,TCP 堆栈是否真的会继续尝试传输数据?这是否像在通过设置 SO_LINGER 调用 close() 之前自己等待任意超时一样可靠?
也就是说,是否应用相同的 TCP 超时,还是更短?毕竟,由于发送缓冲区较大且连接速度较慢,因此实际传输所有缓冲数据的时间可能会很长。
我对收到最后一个字节发送的通知不感兴趣;我只是希望它们最终尽可能可靠地到达远程主机。
应用层确认不是一个选项(协议是 HTTP,我正在编写一个小型服务器)。
【问题讨论】:
-
这取决于实现,但一般来说,是的,
close()将在实际拆除套接字之前刷新缓冲区中剩余的任何数据。如果您在调用close()之外终止整个过程,里程可能会有所不同。 -
如果您退出流程,@aroth 里程将不发生变化。这两种情况没有区别。如果您想保持相反的情况,请提供权威参考。
-
@EJP - 关于在任意程序中可能发生什么的权威参考?我不认为这样的事情存在。但这很简单,可以举一个似是而非的例子。假设您有一个程序将所有网络操作委托给一个单独的线程,就像大多数程序一样。当后台线程调用
close()时,主线程可能会终止进程(优雅地或以其他方式)。在这种情况下调用会成功吗?我对此表示怀疑。当然,您所说的对于任何单线程程序都应该成立。但并非所有程序都是单线程的。 -
@aroth 不,权威参考,说明您所说的“里程可能会有所不同”。你不会找到一个。套接字关闭是应用程序退出时由应用程序或内核完成的套接字关闭。如果您有反例,请再次提供。