[erlang-questions] gen_tcp question

Serge Aleynikov <>
Mon Sep 18 16:45:25 CEST 2006

Joe Armstrong (TN/EAB) wrote:
> 	{ok, L} = gen_tcp:listen(Port,
> [{length,4},binary,{active,true}]),

I hope it is a typo, because there's no {length, N} socket option.  Did 
you, perhaps, mean {packet, 4}?

> loop(S, C) ->
>      receive
>          {tcp, S, Bin} ->              %% <----- Is Bin of length 4
> here?????????????
>               C ! binary_to_term(Bin),   
>               loop(S, C);
>          {tcp_closed, S} ->
> 	        C ! closed;
> 	   {msg, Term} ->
>               gen_tcp:send(S, term_to_binary(Term)),
> 	        loop(S, C);
>          close ->
> 	        gen_tcp:close(S)	
> 	end        

I wouldn't be able to say how this was *supposed* to work since this is 
unclear from the documentation.  However, by knowing the details of the 
inet_drv C driver I can tell you that the difference in the driver 
behavior in presence of the {active, true} option is that in contrast to 
the gen_tcp:recv/2, when the driver is getting a command from the Erlang 
process to issue a socket read, the active option initiates a socket 
read upon detecting some data on the socket in exactly the same manner 
as if the gen_tcp:recv(Sock, 0) was called.  In both cases you are 
guaranteed to get the *full non-fragmented* packet of length M (where M 
is read from the message header determined by the N bytes with respect 
to the {packet, N} option).

Note that since gen_tcp:recv(Sock, M), where M > 0 is not a possible 
call for sockets with {packet, N} where N =/= 0, it would also be 
meaningless to have the {packet, N} option if it didn't guarantee 
non-fragmented delivery of packets.

> I need the active=true mode for this since loop has to handle messages
> from both C and S - so I don't want to block in gen_tcp:recv

Since you are including this example in the book, I'd recommend 
additionally showing how to use active sockets and still preserve flow 
control without gen_tcp:recv, so that you can implement the server using 
the standard OTP gen_server behavior.  This can be accomplished by using 
{active, once} option.

> Now if the answer to this question is in the documentation I can't seem
> to find it
> the setopts documentation says that a 4 byte header is appended to the
> TCP data - that's
> all.

I also don't believe this is documented.



>> -----Original Message-----
>> From: Jani Hakala [mailto:] 
>> Sent: den 14 september 2006 15:33
>> To: 
>> Cc: Joe Armstrong (TN/EAB)
>> Subject: Re: [erlang-questions] gen_tcp question
>> "Joe Armstrong (TN/EAB)" <> writes:
>>> The behaviour appears not to be documented
>> Meaning of {packet,N} is explained in man inet, inet:setopts 
>> The behaviour of gen_tcp:recv is explained in man gen_tcp
>> Jani Hakala
> _______________________________________________
> erlang-questions mailing list
> http://www.erlang.org/mailman/listinfo/erlang-questions

More information about the erlang-questions mailing list