gen_tcp:recv - last segement when closed port

Per Hedeland hedeland@REDACTED
Sun Mar 12 17:14:46 CET 2006

"Valentin Micic" <valentin@REDACTED> wrote:
>If application read only fraction of the data available, as per your 
>assertion, arrival of FIN-1 shall not inform App about remote closure. This 
>leaves App free to send any kind of data back to the remote peer. However, 
>when remote peer receives such data, considering that it is in FIN-WAIT 
>state, it has no choice but to reply with RESET, and hence force receive 
>buffer on App side to flush all the data.

Mostly a nitpick for the case you describe, but no, this isn't true. It
is perfectly possible to continue to receive in FIN-WAIT - in fact this
is fundamental for how "plain" HTTP/1.0 (i.e. without persistent
connections, Content-Length, and other fancy stuff) works:

The client sends the request and immediately closes the sending side of
the connection (using shutdown()), which causes FIN to be sent and
FIN-WAIT-1 to be entered. The server reads the request until the
end-of-file indication that is the user-level-visible result of FIN
having been received, and then sends the response (by then the client is
likely in FIN-WAIT-2), and likewise immediately closes (normally with a
"full" close()). The client finally reads the response until the
end-of-file indication etc.

Anyone who thinks that this procedure might lead to loss of data
(assuming correctly functioning applications and available network
connectivity) will have a hard time explaining the initial success of
the web...

In your case however there had presumably been a "full" close() at the
remote end - the difference isn't really reflected in the TCP state
machine - in which case the remote must indeed send RST in response to
incoming data, to inform the sender that the data will not be delivered.

> I had a situation like this many 
>years ago, and assocciated the loss of data to close request, while infact, 
>it was App sending data causing remote peer to issue RESET request, and 
>hence flushing the tcp buffer on App side.

This sounds like a broken application-level protocol though - App
shouldn't be sending data if the remote isn't prepared to receive it...


More information about the erlang-questions mailing list