[erlang-questions] gen_tcp/inet/flow control/misc

Florian Zumbiehl <>
Fri Nov 14 04:58:10 CET 2008


I've got some questions regarding the behaviour of gen_tcp I wasn't quite
able to answer from the documentation I could find on the web.

1. I'm not quite sure how write-side flow control on tcp sockets works.

   At the read side, I understand that using passive or active-once mode
   should cause back-pressure to the sending process to form if consumption
   proceeds slower than the data source's and the network's bandwidths.
   I guess that one usually doesn't really need to know more than that,
   but still: What buffers are there in between the file descriptor
   and the gen_tcp API? And which is the buffer affected by the recbuf

   At the write side, though, it's rather unclear to me how flow control
   works. Given that there is a send_timeout option and that gen_tcp:send/2
   can return {error,timeout}, it seems likely that gen_tcp:send/2 works
   at least somewhat synchronously. On the other hand, there is the
   delay_send option, the documentation for which claims that "the driver
   will use any means available to queue up the message"--which sounds
   to me like completely asynchronous operation, so that no back-pressure
   would be felt by the inet:send/2-ing process, no matter how slow the
   data sink. However, it's neither stated that these options were somehow
   incompatible, nor can I find any explanation as to what interaction
   between these options to expect.

   So, the question basically condenses down to: What buffers are
   there in between the fd and the gen_tcp API, once again, and
   how do they interact with the various options? And how would
   I implement flow control at the write side?

   While I am at it: Is there any usual way for implementing (read: a
   ready-to-use implementation of) a limited-length (blocking) data queue
   between processes? Basically, what you'd need for implementing
   flow control between an outside source and an outside sink without
   the penalty of making all the processes in between work synchronously.

2. There is the wonderful packet type "line", the documentation for which
   says "Line mode, a packet is a line terminated with newline, lines
   longer than the receive buffer are truncated." Now, this may already
   have been answered in the above questions, but: I set recbuf to
   5. Assuming that the unit for the recbuf size is bytes, it doesn't
   seem to work as documented: Lines much longer than 5 bytes were
   delivered to the receiving process. So, what's the real semantics
   of this?

3. What is the effect of the exit_on_close option? The documentation
   just states that you need it if you want to handle a half-closing
   peer--but nothing as to why it's an option at all, under which
   circumstances not to specify it, or just, what the effects actually
   are. In particular, it would be interesting to know how you learn
   about the peer shutting down its sending direction ...

Well, that's it for now ;-)


More information about the erlang-questions mailing list