Writing on a TCP socket closed by the peer

吃可爱长大的小学妹 提交于 2019-12-01 05:46:25

问题


I have a client-server application where each side communicate with the other via TCP socket.

I properly establish the connection and then I crash the server BEFORE any data is written on the socket by the client.
What I see is that the first write() attempt (client-side) is successful and it returns the actual number of written bytes, while the following ones return (as I expected) -1 (receiving a SIGPIPE) and errno=EPIPE.

Why the first write() is successful even if the socket is already closed?

EDIT Sometimes also the following write() have a positive return values, as if everything goes well.


回答1:


You're confused by what the return value of write() means. It doesn't mean, "the peer got the data and acknowledged it". Instead, it means, "I buffered so-many bytes to send to the peer and they're my responsibility now, so you can forget about them (and I don't have any pending errors)".

That is, if the TCP stack accepts the write and returns n bytes, that doesn't mean they've been written yet, just queued for writing. It'll take some time, perhaps 30s after it starts sending network traffic, before the stack gives up and returns an error to you. During that time, you could have done several calls to write() which were successful at queueing data for sending. (The write error will be returned in c.30s if the peer has vanished, or immediately if the peer can be contacted and sends a RST packet straight away to indicate the connection is dead.)




回答2:


This has to do with how TCP/IP works, that can be roughly described as two mostly independent half-connections. When you close the socket at the server, the client is told that it will not receive further data from the C<-S half-connection, waking up read() immediatly, but not about the C->S direction. It only gets a reply resetting the connection after it tries to send some data. I recommend the TCP/IP Guide for further details.

The reason why sometimes you can write() twice is that you write faster than the round-trip time and can squeeze a second write() before the reply to the first one.




回答3:


I'm using the following method to detect a disconnected server condition:

After getting the select() timeout on a socket (nothing was received, though was supposed to), the 'system("ping -c 1 -w 1 server");' command is activated. If the server is up and just lagging, the ping command will return in less than 0.1 seconds. Otherwise (the server is down), the ping command will return in 1 second.



来源:https://stackoverflow.com/questions/15406097/writing-on-a-tcp-socket-closed-by-the-peer

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