Receiving data from already closed socket?

烂漫一生 提交于 2019-12-07 04:11:19

问题


Suppose I have a server application - the connection is over TCP, using UNIX sockets.

The connection is asynchronous - in other words, clients' and servers' sockets are non-blocking.

Suppose the following situation: in some conditions, the server may decide to send some data to a connected client and immediately close the connection: using shutdown with SHUT_RDWR.

So, my question is - is it guaranteed, that when the client call recv, it will receive the (sent by the server) data?

Or, to receive the data, recv must be called before the server's shutdown? If so, what should I do (or, to be more precise, how should I do this), to make sure, that the data is received by the client?


回答1:


You can control this behavior with "setsockopt(SO_LINGER)":

  • man setsockopt

SO_LINGER Waits to complete the close function if data is present. When this option is enabled and there is unsent data present when the close function is called, the calling application is blocked during the close function until the data is transmitted or the connection has timed out. The close function returns without blocking the caller. This option has meaning only for stream sockets.

See also:

  • man read

  • Beej's Guide to Network Programming




回答2:


There's no guarantee you will receive any data, let alone this data, but the data pending when the socket is closed is subject to the same guarantees as all the other data: if it arrives it will arrive in order and undamaged and subject to TCP's best efforts.

NB 'Asynchronous' and 'non-blocking' are two different things, not two terms for the same thing.




回答3:


Once you have successfully written the data to the socket, it is in the kernel's buffer, where it will stay until it has been sent and acknowledged. Shutdown doesn't cause the buffered data to get lost. Closing the socket doesn't cause the buffered data to get lost. Not even the death of the sending process would cause the buffered data to get lost.

You can observe the size of the buffer with netstat. The SendQ column is how much data the kernel still wants to transmit.

After the client has acknowledged everything, the port disappears from the server. This may happen before the client has read the data, in which case it will be in RecvQ on the client. Basically you have nothing to worry about. After a successful write to a TCP socket, every component is trying as hard as it can to make sure that your data gets to the destination unharmed regardless of what happens to the sending socket and/or process.

Well, maybe one thing to worry about: If the client tries to send anything after the server has done its shutdown, it could get a SIGPIPE and die before it has read all the available data from the socket.



来源:https://stackoverflow.com/questions/11889791/receiving-data-from-already-closed-socket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!