Questions regarding TCP sockets

Raimo Niskanen raimo@REDACTED
Mon Nov 12 10:00:48 CET 2001


Shafia Kausar wrote:
> 
> Hi,
> 
> I currently have an active TCP socket which is getting swamped by bursts
> of short messages sent by the other end resulting in processor overload.
> I would like to introduce flow control to prevent incoming bursts of
> data, for which, I understand that I need to change the socket to a
> passive mode.
> 
> But I am not sure how to implement the receipt of packets from the
> socket. More precisely  - what is the difference between an active and
> passive socket? How does a passive socket introduce flow control?
> 

TCP has got flow control between nodes, so if you create a socket
connection and starts sending data in at one end, not reading at the
other, the send operations will start to block.

A gen_tcp active socket automatically reads data from the socket if
there is any available, which might eventually fill the Erlang process
receive message queue, if the process does not handle the data fast
enough.

A gen_tcp passive socket does not read any data from the socket other
then when gen_tcp:recv/2 is called, which might fill the TCP internal
buffers at both ends and eventually start blocking process doing the
gen_tcp:send/2 calls (or corresponding, it does not have to be an Erlang
implementation at the other end). This is generally what you want to
happen.

> What is the purpose of the length parameter in the function call
> 
>         gen_tcp:recv(sock, length).
> 
> i.e. how is the length related to the receive buffer of TCP
> 

The 'length' argument becomes the buffer length for the 'recv' system
call (unix), and does not relate to TCP's internal receive buffers. The
data returned by the call is often less.

> So far the only difference in behavior I have seen is that the active
> socket reads every message it receives and sends it to the application,
> while a passive socket requires the user to read the socket. I am
> assuming that reading of the socket at intervals rather than
> continuously introduces flow control.
> 

Even if you read continously you will probably not choke the Erlang node
by an exploding process message receive queue.

> If my above assumption is correct -  how frequent should the read be to
> introduce an optimum flow control mechanism? How many bytes do we read
> at a time? Does the length parameter control the size of the receive
> buffer/advertised receiver window? How much of additional flow control
> do we achieve by using the timeout parameter in gen_tcp:recv/3
> 

Very application dependant. The timeout parametar is only needed when
you do not need flow control, i.e when you have to wait for incoming
data.

> Can I have two different processes interacting with the passive socket
> -  one process reads the socket in a loop while the other sends to the
> socket? I was thinking about this to free the process which would
> otherwise be tied to the receive loop. Would this beat the whole purpose
> of the passive socket?
> 

You can also try the '{active, once}' option. This would only read one
message automatically from the socket, not having to get stuck in a
gen_tcp:recv/2 call. When you are ready for another message just call
inet:setopts(Socket, [{active, once}]), and you will get more data when
it arrives.

> What are the default values of the send/receive buffer in OTP? I
> understand that these are set by the OS and are also configurable when
> we define the socket parameters but if this is not defined by the user
> does OTP override the OS defaults (possibly?)
> 

I can dig this up if really necessary.


/ Raimo Niskane, Erlang/OTP, Ericsson UAB



More information about the erlang-questions mailing list