6

假设我有一个服务器应用程序 - 使用 UNIX 套接字通过 TCP 连接。

连接是异步的——换句话说,客户端和服务器的套接字是非阻塞的。

假设以下情况:在某些情况下,服务器可能决定向已连接的客户端发送一些数据并立即关闭连接:使用shutdownwith SHUT_RDWR

所以,我的问题是 - 是否可以保证,当客户端调用时recv,它将接收(由服务器发送的)数据?

或者,要接收数据,recv必须在服务器的shutdown? 如果是这样,我应该怎么做(或者,更准确地说,我应该怎么做),以确保数据被客户端接收?

4

3 回答 3

5

您可以使用“setsockopt(SO_LINGER)”控制此行为:

SO_LINGER 如果存在数据,则等待完成关闭功能。如果启用此选项并且在调用关闭函数时存在未发送的数据,则在关闭函数期间调用应用程序将被阻塞,直到数据传输或连接超时。close 函数在不阻塞调用者的情况下返回。此选项仅对流套接字有意义。

也可以看看:

于 2012-08-09T18:38:41.737 回答
5

不能保证你会收到任何数据,更不用说这些数据了,但是当套接字关闭时等待处理的数据与所有其他数据一样受到同样的保证:如果它到达,它将按顺序到达并且完好无损,并且受 TCP 的最佳努力。

注意“异步”和“非阻塞”是两个不同的东西,而不是同一事物的两个术语。

于 2012-08-09T22:26:58.490 回答
4

一旦你成功地将数据写入套接字,它就会在内核的缓冲区中,直到它被发送和确认为止。关机不会导致缓冲数据丢失。关闭套接字不会导致缓冲数据丢失。即使发送进程的死亡也不会导致缓冲数据丢失。

您可以使用 观察缓冲区的大小netstat。SendQ 列是内核仍要传输的数据量。

客户端确认所有内容后,该端口将从服务器中消失。这可能发生在客户端读取数据之前,在这种情况下,它将在客户端的 RecvQ 中。基本上你没有什么可担心的。在成功写入 TCP 套接字后,每个组件都在尽最大努力确保您的数据不受损害地到达目的地,而不管发送套接字和/或进程发生了什么。

好吧,也许要担心一件事:如果客户端在服务器关闭后尝试发送任何内容,它可能会在从套接字读取所有可用数据之前获得一个 SIGPIPE 并死掉。

于 2012-08-12T22:26:00.137 回答