[erlang-questions] how to flush a gen_tcp socket on close?

Andreas Schultz <>
Tue Apr 3 15:38:41 CEST 2012


Am 02.04.2012 um 12:30 schrieb Per Hedeland <>:

> Matthias Lang <> wrote:
>> 
>> On Monday, April 02, Andreas Schultz wrote:
>> 
>>> gen_tcp sockets do buffer sends internaly. It seems, when
>>> calling close on them, the buffered data is not flushed out,
>>> but simply discarded .
>>> I was expecting that a close on an socket with outstanding
>>> send data would block until that data has been send, but that
>>> seems not to happen. In fact, that might be a bug????
>> 
>> I would also expect a socket to send all data. So your description
>> of what actually happens is surprising.
> 
> +1. I would actually go as far as saying that gen_tcp would be unusable
> for many applications if close/1 discarded buffered data. *Blocking* on
> close is another thing though, I don't expect that - the C API doesn't
> block on close either, you can ask for it via setsockopt(SO_LINGER), but
> it isn't the default.

Prim_inet has an internal send buffer and it has to make sure that this is flushed, so I think close should block. I found the part where it does this in the erlang part of inet, however there seems to be a timeout of 5 seconds.

In my case the receiver is to slow to process all the data, sender does 10k packets of 1k size, the receiver only gets the first 2000 packets. It might well be that I hit the close timeout and inet discards the rest of the send queue.

The fix should be simple, limit the send queue size.
> 
>> Can you provide a minimal but complete code which demonstrates what
>> you're seeing?

I'm on vacation for a few day, I will build a demo next week.

> 
> +1 again.
> 
> And to comment on the other reply, using shutdown/2 should most
> certainly not be needed for this - the only purpose of using that is to
> do a "half close".

Shutdown seems not to process the send queue.
> 
> --Per Hedeland
> 
Andreas



More information about the erlang-questions mailing list