首页 文章

send()后直接关闭()套接字:不安全?

提问于
浏览
25

在最后 send() 之后直接 close() 套接字是明智/安全的吗?

我知道TCP应该尝试在关闭套接字后尝试在发送缓冲区中传递所有剩余数据,但是我真的可以依靠它吗?

我确保我的接收缓冲区中没有剩余数据,因此在关闭后不会发送任何RST .


在我的例子中,close在调用 exit() 之前实际上是最后一个代码语句 .

即使在发送数据的进程终止后,TCP堆栈是否会继续尝试传输数据?在通过设置SO_LINGER调用 close() 之前,自己等待任意超时是否可靠?

也就是说,应用相同的TCP超时,还是缩短?毕竟,使用大的发送缓冲区和慢速连接,实际传输所有缓冲数据的时间可能很长 .


我对收到最后一个字节的通知并不感兴趣;我只是希望他们最终尽可能可靠地到达远程主机 .

应用程序层确认不是一个选项(协议是HTTP,我正在编写一个小型服务器) .

1 回答

  • 23

    我一直在阅读ultimate SO_LINGER page . 我建议你也读它 . 它讨论了与TCP套接字有关的大数据传输的边缘情况 .

    我不是SO_LINGER的专家,但是在我的服务器代码上(仍在积极开发中)我做了以下事情:

    • 在通过send()发送最后一个字节后,我调用“shutdown(sock,SHUT_WR)”来触发FIN发送 .

    • 然后等待对该套接字的后续recv()调用返回0(或者recv返回-1,而errno是EAGAIN / EWOULDBLOCK的其他内容) .

    • 然后服务器在套接字上执行close() .

    假设客户端在收到响应的所有字节后首先关闭其套接字 .

    但是我确实在最终的send()和recv()指示EOF之间执行了超时 . 如果客户端永远不会关闭他的连接结束,服务器将放弃等待并关闭连接 . 这次超时我的时间是45-90秒 .

    我的所有套接字都是非阻塞的,我使用poll / epoll来通知连接事件,作为提示是否有时间尝试再次调用recv()或send() .

相关问题