Quantcast

[erlang-questions] Installing Erlang/OTP R11B-1 on Xubuntu laptop

classic Classic list List threaded Threaded
21 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

[erlang-questions] Installing Erlang/OTP R11B-1 on Xubuntu laptop

Vlad Dumitrescu-2

Hi,

There is an erlang distribution for Ubuntu, but I'm not sure how new it is (it may be R10). I think it's to be found in the 'universe'  - just serch for erlang in synaptic.

There is a private newer distribution, but last I checked it was only a Debian package (meaning it would need manual setup).

In any case, I didn't have any problem compiling from source on an out-of-the-box Ubuntu 6.06.

Good luck!
best regards,
Vlad
_________________________________________________________
Post sent from http://www.trapexit.org
_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

[erlang-questions] gen_tcp question

Joe Armstrong (TN/EAB)
 
I have a question about gen_tcp

A client does this:

        {ok, Port} = gen_tcp:connect(Host, Post, [binary,{packet,N}])
        get_tcp:send(Port, <<Bin>>)
       
The server

        calls gen_tcp:listen(Port, [binary,{packet,N}])

Then goes into a receive loop to receive messages

Questions:

     1) is <<Bin>> delivered as a single message to the server program?
        or is the packet fragmented.

     2) Does fragmentation or not depend upon N (the packet size)
         must N be > 0 for the receiver to be able to reconstruct the
         fragments (if fragmented?)

The behaviour appears not to be documented

/Joe

   

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Vlad Dumitrescu-2
On 9/14/06, Joe Armstrong (TN/EAB) <[hidden email]> wrote:
>     1) is <<Bin>> delivered as a single message to the server program?
>        or is the packet fragmented.
>     2) Does fragmentation or not depend upon N (the packet size)
>         must N be > 0 for the receiver to be able to reconstruct the
>         fragments (if fragmented?)

Hi,

I think the behaviour isn't documented because it isn't dictated by
Erlang, but is dictated by the TCP parameters of the socket. Any TCP
packet may be fragmented (it certainly is if it is larger then the
current MTU), but I think that even servers along the way (if it's a
remote connection) may further fragment it.

So to be sure, assume it's fragmented.

If N=0 you will have to have your own way to be to reconstruct each
message from the TCP stream. Relying on each message to be delivered
separately isn't working. I know from personal experience :-)

best regards,
Vlad
_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Sean Hinde
In reply to this post by Joe Armstrong (TN/EAB)
Hi Joe,

I have used this technique with really quite large packets and it  
always seemed to do the right thing.

I typically use {packet, 2} so that the other end cannot fill up my  
machine with DoS style packets.

Sean


On 14 Sep 2006, at 12:35, Joe Armstrong ((TN/EAB)) wrote:

>
> I have a question about gen_tcp
>
> A client does this:
>
> {ok, Port} = gen_tcp:connect(Host, Post, [binary,{packet,N}])
> get_tcp:send(Port, <<Bin>>)
>
> The server
>
> calls gen_tcp:listen(Port, [binary,{packet,N}])
>
> Then goes into a receive loop to receive messages
>
> Questions:
>
>      1) is <<Bin>> delivered as a single message to the server  
> program?
>         or is the packet fragmented.
>
>      2) Does fragmentation or not depend upon N (the packet size)
>          must N be > 0 for the receiver to be able to reconstruct the
>          fragments (if fragmented?)
>
> The behaviour appears not to be documented
>
> /Joe
>
>
>
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://www.erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Serge Aleynikov
In reply to this post by Joe Armstrong (TN/EAB)
Joe Armstrong (TN/EAB) wrote:

>  
> I have a question about gen_tcp
>
> A client does this:
>
> {ok, Port} = gen_tcp:connect(Host, Post, [binary,{packet,N}])
> get_tcp:send(Port, <<Bin>>)
>
> The server
>
> calls gen_tcp:listen(Port, [binary,{packet,N}])
>
> Then goes into a receive loop to receive messages
>
> Questions:
>
>      1) is <<Bin>> delivered as a single message to the server program?
>         or is the packet fragmented.

I would say that since the tcp_recv call in inet_drv.c is aware of the
{packet,N} option set on the socket, gen_tcp:recv(Sock, 0) will (memory
permitting) deliver a complete packet of N bytes to the caller.  However
the packet may get fragmented in the transport layer because of the MTU
size excess, though this should be transparent to the caller.

>      2) Does fragmentation or not depend upon N (the packet size)
>          must N be > 0 for the receiver to be able to reconstruct the
>          fragments (if fragmented?)

I think this depends on which socket option is set.  For {packet,N}
doing gen_tcp:recv(Sock, M), where M != 0 will return an einval (if
memory serves) error.  If you are using raw socket option, there is a
16M limit on the size of M.  You'll get an enomem error in that case.

> The behaviour appears not to be documented
>
> /Joe

Regards,

Serge
_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Joe Armstrong (TN/EAB)
In reply to this post by Sean Hinde

It might well be that it

   ... "seemed to do the right thing" ...

But what I want to knwo is if the gen_tcp layer is *designed* and
programmed
to only deliver packets of exactly the right length.

The fact that your packets are not fragmented might be accidental or by
design

Is this an accidental propery of do I have to add a layer of code that
does the
refragmentation - I could read the code, but that would be cheating.

Reading the code will tell me what the program actually does, and NOT
what it
is supposed to do.

I guess Tony knows if he's reading this :-)

/Joe


> -----Original Message-----
> From: Sean Hinde [mailto:[hidden email]]
> Sent: den 14 september 2006 14:22
> To: Joe Armstrong (TN/EAB)
> Cc: [hidden email]
> Subject: Re: [erlang-questions] gen_tcp question
>
> Hi Joe,
>
> I have used this technique with really quite large packets
> and it always seemed to do the right thing.
>
> I typically use {packet, 2} so that the other end cannot fill
> up my machine with DoS style packets.
>
> Sean
>
>
> On 14 Sep 2006, at 12:35, Joe Armstrong ((TN/EAB)) wrote:
>
> >
> > I have a question about gen_tcp
> >
> > A client does this:
> >
> > {ok, Port} = gen_tcp:connect(Host, Post, [binary,{packet,N}])
> > get_tcp:send(Port, <<Bin>>)
> >
> > The server
> >
> > calls gen_tcp:listen(Port, [binary,{packet,N}])
> >
> > Then goes into a receive loop to receive messages
> >
> > Questions:
> >
> >      1) is <<Bin>> delivered as a single message to the server
> > program?
> >         or is the packet fragmented.
> >
> >      2) Does fragmentation or not depend upon N (the packet size)
> >          must N be > 0 for the receiver to be able to
> reconstruct the
> >          fragments (if fragmented?)
> >
> > The behaviour appears not to be documented
> >
> > /Joe
> >
> >
> >
> > _______________________________________________
> > erlang-questions mailing list
> > [hidden email]
> > http://www.erlang.org/mailman/listinfo/erlang-questions
>
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Sean Hinde

On 14 Sep 2006, at 13:33, Joe Armstrong ((TN/EAB)) wrote:

>
> It might well be that it
>
>    ... "seemed to do the right thing" ...

Well, It did the right thing consistently for some years with  
messages much larger that can be carried in a single LAN packet.  
Personally I would take that as greater proof than reading it in the  
documentation.

Others of a different persuasion would believe that if it was not  
written in the documentation then I had in fact created a timebomb  
guaranteed to fail at the worst possible moment in the future !

Only Ericsson can make any documented guarantees about the default  
system, not even Tony can provide anything other that a statement of  
his intent when he wrote it.


Sean

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Joe Armstrong (TN/EAB)

I'm not interested in what is actually does -
I'm interested in what it's supposed to do.

The documentation is supposed to tell you what the program is supposed
to do
and I suppose that it is reasonable to suppose that people are supposed
to
send error messages if they suppose that the program does not
do what might be supposed from the documentation.

<I'm almost proud of that sentence>

/Joe


> -----Original Message-----
> From: Sean Hinde [mailto:[hidden email]]
> Sent: den 14 september 2006 14:46
> To: Joe Armstrong (TN/EAB)
> Cc: [hidden email]; [hidden email]
> Subject: Re: [erlang-questions] gen_tcp question
>
>
> On 14 Sep 2006, at 13:33, Joe Armstrong ((TN/EAB)) wrote:
>
> >
> > It might well be that it
> >
> >    ... "seemed to do the right thing" ...
>
> Well, It did the right thing consistently for some years with
> messages much larger that can be carried in a single LAN packet.  
> Personally I would take that as greater proof than reading it
> in the documentation.
>
> Others of a different persuasion would believe that if it was
> not written in the documentation then I had in fact created a
> timebomb guaranteed to fail at the worst possible moment in
> the future !
>
> Only Ericsson can make any documented guarantees about the
> default system, not even Tony can provide anything other that
> a statement of his intent when he wrote it.
>
>
> Sean
>
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Vlad Dumitrescu-2
In reply to this post by Sean Hinde
On 9/14/06, Sean Hinde <[hidden email]> wrote:
> Well, It did the right thing consistently for some years with
> messages much larger that can be carried in a single LAN packet.
> Personally I would take that as greater proof than reading it in the
> documentation.

Then I suppose the problems I had (for some while ago, I think it was
R7 or R8) were not caused by this issue or was fixed since. Good to
know!

regards,
Vlad
_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Sean Hinde
In reply to this post by Joe Armstrong (TN/EAB)
Joe,

I was not disagreeing with you that it should be documented. I  
suppose I was making an observation on human (and corporate) behaviour.

Personally I am happy to derive an intent from the combination of the  
existing documentation and my own testing. If it ended up not working  
as implied by the documentation then I would have had no hesitation  
to raise a trouble ticket using the commercial support option and  
blag it. Others are not happy to rely on this level of assumption so  
it should of course be documented.

To the point in hand:

I am sure Tony could make some statement of what it was supposed to  
do when he wrote it, but that is surely not enough.

Ericsson might have a plan to change the undocumented behaviour so it  
only works for packets without an F in the length in an unspecified  
number base.

So, only Ericsson can make any statement of what the program is  
supposed to do now and in the future. And that place is the  
documentation and any support contracts you might have with them.

BR,
Sean

On 14 Sep 2006, at 13:53, Joe Armstrong ((TN/EAB)) wrote:

>
> I'm not interested in what is actually does -
> I'm interested in what it's supposed to do.
>
> The documentation is supposed to tell you what the program is supposed
> to do
> and I suppose that it is reasonable to suppose that people are  
> supposed
> to
> send error messages if they suppose that the program does not
> do what might be supposed from the documentation.
>
> <I'm almost proud of that sentence>
>
> /Joe
>
>
>> -----Original Message-----
>> From: Sean Hinde [mailto:[hidden email]]
>> Sent: den 14 september 2006 14:46
>> To: Joe Armstrong (TN/EAB)
>> Cc: [hidden email]; [hidden email]
>> Subject: Re: [erlang-questions] gen_tcp question
>>
>>
>> On 14 Sep 2006, at 13:33, Joe Armstrong ((TN/EAB)) wrote:
>>
>>>
>>> It might well be that it
>>>
>>>    ... "seemed to do the right thing" ...
>>
>> Well, It did the right thing consistently for some years with
>> messages much larger that can be carried in a single LAN packet.
>> Personally I would take that as greater proof than reading it
>> in the documentation.
>>
>> Others of a different persuasion would believe that if it was
>> not written in the documentation then I had in fact created a
>> timebomb guaranteed to fail at the worst possible moment in
>> the future !
>>
>> Only Ericsson can make any documented guarantees about the
>> default system, not even Tony can provide anything other that
>> a statement of his intent when he wrote it.
>>
>>
>> Sean
>>
>>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Sean Hinde
In reply to this post by Vlad Dumitrescu-2

On 14 Sep 2006, at 13:58, Vlad Dumitrescu wrote:

> On 9/14/06, Sean Hinde <[hidden email]> wrote:
>> Well, It did the right thing consistently for some years with
>> messages much larger that can be carried in a single LAN packet.
>> Personally I would take that as greater proof than reading it in the
>> documentation.
>
> Then I suppose the problems I had (for some while ago, I think it was
> R7 or R8) were not caused by this issue or was fixed since. Good to
> know!

Aha, but if it is not documented then YMMV!

Sean



_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Jani Hakala
In reply to this post by Joe Armstrong (TN/EAB)
"Joe Armstrong (TN/EAB)" <[hidden email]> 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
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Sean Hinde

On 14 Sep 2006, at 14:32, Jani Hakala wrote:

> "Joe Armstrong (TN/EAB)" <[hidden email]> 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

Well observed!

My assumption (there we go again) was that Joe must have read the  
documentation in order to have discover the existence of {packet, N},  
but found it lacking. Reading the page more carefully now it is clear  
that it does specify the behaviour.

Where you perchance peeking under the hood to discover this option  
Joe ? :-)

Sean
_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] Installing Erlang/OTP R11B-1 on Xubuntu laptop

Gerd Flaig
In reply to this post by Vlad Dumitrescu-2
Hi,

"vladdu" <[hidden email]> writes:

> There is an erlang distribution for Ubuntu, but I'm not sure how new
> it is (it may be R10). I think it's to be found in the 'universe' -
> just serch for erlang in synaptic.
>
> There is a private newer distribution, but last I checked it was only
> a Debian package (meaning it would need manual setup).

for those who like packages, it's also possible to compile the Debian
sid Erlang source package. I did that in a clean Ubuntu 6.01.1 chroot
and put the result in my private repository. The source.list line is:

   deb http://nxdomain.org/ubuntu dapper/

Contents right now:

   erlang-x11 erlang-nox erlang-src erlang-examples erlang-mode erlang
   erlang-base erlang-dev erlang-base-hipe erlang-doc-html
   erlang-manpages (all packages have version 11.b.1-1,
   i.e. Erlang/OTP version R11B-1)

      Goodbyte, Gerd.
--
The last thing one knows in constructing a work is what to put first.
                -- Blaise Pascal

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Joe Armstrong (TN/EAB)
In reply to this post by Sean Hinde
Hi Sean,

Your assumption is correct - I did read the manual first
and Jani answered a question that I had not asked.

My origonal example opened the socket in active mode,
and I'm not using gen_tcp:recv to receive data at all
so the behaviour of recv is irrelevant.

>From what's been said here, it seems I should be setting
active=false and using recv, rather than doing things the way I was
doing
them.

Why all the questions:? I'm writing THE book (at last) this
means you'll just have to put up with loads of very detailed
questions. This is because when I say in the book

   " so and so works like this ..."

I want it to be correct

/Joe


 

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On Behalf Of Sean Hinde
> Sent: den 14 september 2006 15:46
> To: Erlang Questions
> Subject: Re: [erlang-questions] gen_tcp question
>
>
> On 14 Sep 2006, at 14:32, Jani Hakala wrote:
>
> > "Joe Armstrong (TN/EAB)" <[hidden email]> 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
>
> Well observed!
>
> My assumption (there we go again) was that Joe must have read
> the documentation in order to have discover the existence of
> {packet, N}, but found it lacking. Reading the page more
> carefully now it is clear that it does specify the behaviour.
>
> Where you perchance peeking under the hood to discover this
> option Joe ? :-)
>
> Sean
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://www.erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Sean Hinde
Hi Joe,

If the document does not say that this can only be used in passive  
mode then I read it as saying it should be present and correct in  
active mode. The passage simply refers to "receiving", which should  
mean all receive modes.

FWIW I was referring to active mode in my replies..

I also see that {active, once} is now properly documented which is  
great - it means that the book could describe the very smartest way  
to use sockets :-)

It is truly exciting to see you are back on the book drive. I'm sure  
we are all here to help with your extremely welcome effort!

Finally, for me the book should always refer to best "real world"  
practice. If Ericsson must be persuaded to fix the documentation in  
some areas then even better.

BR,
Sean



On 18 Sep 2006, at 08:54, Joe Armstrong ((TN/EAB)) wrote:

> Hi Sean,
>
> Your assumption is correct - I did read the manual first
> and Jani answered a question that I had not asked.
>
> My origonal example opened the socket in active mode,
> and I'm not using gen_tcp:recv to receive data at all
> so the behaviour of recv is irrelevant.
>
> From what's been said here, it seems I should be setting
> active=false and using recv, rather than doing things the way I was
> doing
> them.
>
> Why all the questions:? I'm writing THE book (at last) this
> means you'll just have to put up with loads of very detailed
> questions. This is because when I say in the book
>
>    " so and so works like this ..."
>
> I want it to be correct
>
> /Joe
>
>
>
>
>> -----Original Message-----
>> From: [hidden email]
>> [mailto:[hidden email]] On Behalf Of Sean Hinde
>> Sent: den 14 september 2006 15:46
>> To: Erlang Questions
>> Subject: Re: [erlang-questions] gen_tcp question
>>
>>
>> On 14 Sep 2006, at 14:32, Jani Hakala wrote:
>>
>>> "Joe Armstrong (TN/EAB)" <[hidden email]> 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
>>
>> Well observed!
>>
>> My assumption (there we go again) was that Joe must have read
>> the documentation in order to have discover the existence of
>> {packet, N}, but found it lacking. Reading the page more
>> carefully now it is clear that it does specify the behaviour.
>>
>> Where you perchance peeking under the hood to discover this
>> option Joe ? :-)
>>
>> Sean
>> _______________________________________________
>> erlang-questions mailing list
>> [hidden email]
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Joe Armstrong (TN/EAB)
In reply to this post by Jani Hakala

Hi Jani,

My problem is that I am NOT using gen_tcp:recv at all - I need to open
the
socket in active mode, since I want to receive both messages from the
socket
and send messages to the socket at the same time.

I want to write a middle-man that abstracts out the TCP transport layer
so I write a process that understands TCP and converts terms to packets
etc.

The problem occurs in the following bit of code:


      (C is the Pid of a client)

        {ok, L} = gen_tcp:listen(Port,
[{length,4},binary,{active,true}]),
      {ok, S} = gen_tcp:accept(L),
      loop(S, C).

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 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

So my question is "is Bin" fragmented? - I can easily add an extra layer
for packet recombination inside loop, it is really unclear to me what
the
purpose of saying {packet,4} is in the listen call if it is not to be
used for
recombination.

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.

The behaviour together with recv *is* documented (as you say) but not
when you
don't call recv and process data in active mode

/Joe

> -----Original Message-----
> From: Jani Hakala [mailto:[hidden email]]
> Sent: den 14 september 2006 15:33
> To: [hidden email]
> Cc: Joe Armstrong (TN/EAB)
> Subject: Re: [erlang-questions] gen_tcp question
>
> "Joe Armstrong (TN/EAB)" <[hidden email]> 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
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Jani Hakala
"Joe Armstrong (TN/EAB)" <[hidden email]> writes:

> Hi Jani,
>
> My problem is that I am NOT using gen_tcp:recv at all - I need to open
> the socket in active mode, since I want to receive both messages from
> the socket and send messages to the socket at the same time.
>
I didn't notice that the value {active, true} was being used
implicitly (it being a default value).

> I want to write a middle-man that abstracts out the TCP transport
> layer so I write a process that understands TCP and converts terms to
> packets etc.
>
> The problem occurs in the following bit of code:
>
>
>       (C is the Pid of a client)
>
> {ok, L} = gen_tcp:listen(Port,
> [{length,4},binary,{active,true}]),
>
I assume length is supposed to be packet

>       {ok, S} = gen_tcp:accept(L),
>       loop(S, C).
>
> loop(S, C) ->
>      receive
>          {tcp, S, Bin} -> %% <----- Is Bin of length 4
> here?????????????
>
Length of Bin can be something between 1 byte and several
megabytes. The four extra bytes inserted by using {packet,4} option
are silently removed by underlying inet_drv.

<clip>        
> 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
>
> So my question is "is Bin" fragmented? - I can easily add an extra
> layer for packet recombination inside loop, it is really unclear to me
> what the purpose of saying {packet,4} is in the listen call if it is
> not to be used for recombination.
>
When using {packet,PacketType}, PacketType=1,2 or 4 inet_drv receives
(sends) 1, 2 or 4 byte header before the message you are receiving
(sending). Those bytes correspond to one 8bit, 16bit or 32bit integer
numbers that tell how long the message is going to be. The C-code in
inet_drv then receives (sends) the header and the message in one or
fragments which should happen under the hood.

> 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.
>
>From inet(3erl) manpage
{packet, PacketType} (TCP/IP sockets):
         Defines  the type of packets to use for a socket. The fol-
         lowing values are valid:

         raw | 0:
             No packaging is done.

         1 | 2 | 4:
           Packets consist of a header specifying the number of
           bytes  in  the  packet,  followed  by that number of
           bytes. The length of header can be one, two, or four
           bytes;  the  order  of the bytes is big-endian. Each
           send operation will generate  the  header, and  the
           header  will  be stripped off on each receive opera-
           tion.

         asn1 | cdr | sunrm | fcgi | tpkt | line:
...

Jani Hakala
_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Serge Aleynikov
In reply to this post by Joe Armstrong (TN/EAB)
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.

Regards,

Serge

>> -----Original Message-----
>> From: Jani Hakala [mailto:[hidden email]]
>> Sent: den 14 september 2006 15:33
>> To: [hidden email]
>> Cc: Joe Armstrong (TN/EAB)
>> Subject: Re: [erlang-questions] gen_tcp question
>>
>> "Joe Armstrong (TN/EAB)" <[hidden email]> 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
> [hidden email]
> http://www.erlang.org/mailman/listinfo/erlang-questions
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: [erlang-questions] gen_tcp question

Serge Aleynikov
In reply to this post by Joe Armstrong (TN/EAB)
Joe,

See in-line comments.

Joe Armstrong (TN/EAB) wrote:

> Hi Serge,
>
> It seems to me that the program "does the right thing" (ie recombines
> fragmented packets if packet>0) but that this fact is not documented.
>
> I can understand that {packet,4} adds a 4 byte header on transmission
> so for example, a C program can read this and do whever it wants.
>
> But since the packet,4 header is silently removed in the Erlang case
> (with an active socket) then it become invisible, so I have to add my
> own private size(BIN) (as 4 bytes) in front of each Binary I send
> and then do a re-entrant package reassembly in Erlang (not difficult,
> but it seems a bit daft, since in this case I could just have used
> packet,0
> and done the reassembly anyway)
>  
> Sean, claims that packets are not fragmented, ie that the driver
> reassembles the packets in the case when a packet length is
> given, ie does the right thing

Yes, I concur with Sean's claim.

> Jani said in his last mail
>
> Jani> When using {packet,PacketType}, PacketType=1,2 or 4 inet_drv
> receives
> Jani> (sends) 1, 2 or 4 byte header before the message you are receiving
> (sending). Those bytes
> Jani> correspond to one 8bit, 16bit or 32bit integer numbers that tell
> how long the message is going Jani> to be. The C-code in inet_drv then
> receives (sends) the header and the message in one or
> Jani> fragments which should happen under the hood.
>
> I think this is the opposite of what Sean says
>
> I'm not really sure what " .. and the message in one or two fragments
> .." means.

I am not clear about this sentence either, but I believe Jani meant the
same thing as Sean.

[...]
> It seems to me that the logical behaviour if a packet size is given is
> that the
> Erlang messages are delivered from and to the driver in unfragmented
> binaries
> and that the messages on the line are preceded by a header and then
> possible fragmented.

Correct.  It would be infeasible to assume that messages can be not
fragmented on the transport layer, as it's beyond the control of the C
driver used by the emulator, and is fully dependent on the underlying
protocol.  For instance, in case of SCTP the protocol preserves message
boundaries, so a receive call on an SCTP socket would always guarantee
that a message is either delivered in full, or an error is generated.

> I gave up and started reading inet_drv.c - somewhere in 7071 lines of is
> the answer ...
> but it's not obvious to me where this is ...

You can examine the following functions:

tcp_recv()
tcp_remain()
tcp_deliver()

> I didn't really understand this comment
>
>> 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.
>
> Can you expand on this with (possibly) an example?

Surely!

Let's say that we wanted to accomplish the following:

1. Implement a TCP server receiving client connection requests, and
communicating over some custom protocol.
2. Ensure that there's flow control on the server side and that clients
will not bring down the server by over-flooding its message queue.
3. Use standard OTP behaviors to implement the server process handling
client transactions.

Now, say we learn how to accomplish #1 by studying your tcp_server tutorial:

http://www.sics.se/~joe/tutorials/web_server/tcp_server.erl

#2 can be accomplished by ensuring that if too much traffic is being
generated by clients, we have control over how that traffic is
dispatched to the mailbox of the Erlang server process handling client's
transactions.  This is done by either:

a. Using blocking gen_tcp:recv/2 socket calls. In this case the Erlang
process actively reads data from the socket's buffer, and this data
doesn't reach server process mailbox.  The drawback of this approach is
that it introduces a blocking behavior to the process, and we cannot use
selective receive to respond to other messages coming to the process
mailbox.

b. Using the {active, once} server socket option, and not using the
blocking gen_tcp:recv/2 call, but relying on the gen_tcp's ability to
read and deliver *one* message to the mailbox of the server process.
This is great because we no longer have to deal with blocking calls in
the program, and can use standard gen_server behavior to implement the
server.  The trick is that after receiving and processing a message from
the mailbox, the server needs to issue a call to inet:setopts(Sock,
[{active, once}]) to allow the gen_tcp socket to deliver the next message.

#3 is illustrated by the example below.  Note that I am only including a
few gen_server callbacks that illustrate this point.

-module(custom_server).
-behavior(gen_server).

% Create a new process handling interactions with the client.  If this
% server was a part of an application with a supervisor, we could use
% the simple_one_for_one restart strategy in the supervisor for these
% server processes.  In this case in a production system a crash of
% such a server would automatically generate and log an error report by
% the supervisor / SASL.  The difference in server creation then would
% that we'd call supervisor:start_child/2 instead of gen_server:start
% to create the server process.
new_client(Socket) ->
     {ok, Pid} = gen_server:start(?MODULE, [Socket], []),
     % Here we assume that the calling process had the ownership of the
     % socket.  We need to delegate that ownership to the newly created
     % gen_server in order for the active socket to deliver messages to
     % the proper Pid.
     ok = gen_tcp:controlling_process(Socket, Pid),
     {ok, Pid}.
...

% Let's assume that the socket is created by
init([Socket]) ->
     inet:setopts(Socket, [{active, once}, {packet, 4}, binary]),
     ...
     {ok, State#state{sock = Socket}}.

handle_info({tcp, Socket, Data}, #state{sock=Socket} = State) ->
     % Note that Data is delivered non-fragmented here
     NewState = do_handle_request(Socket, Data, State),
     inet:setopts(Socket, [{active, once}]),
     {noreply, NewState};
...

Please note the following:

1. It is not clear from documentation if the socket returned from the
acceptor call inherits any options given to the listen socket.  I.e. if
the listen socket was opened with:

{ok, ListenSocket} = listen(Port, [{packet, 4}]).

would the server process accepting the client socket need to explicitly
call inet:setopts(Socket, [{packet, 4}]) after the following statement?

{ok, Socket} = accept(ListenSocket).

Or is that option inherited from the listener socket?  I don't think any
options are inherited, and call that explicitly, but it would be nice if
documentation mentioned something about it.

2. Is it possible to turn the socket acceptor process into a gen_server?
  The gen_tcp:accept/1 call is blocking by nature, and I don't see how
this could be done.  However, this server pattern is fairly generic, and
it would be nice if it could be completely mapped to some OTP behavior.

Regards,

Serge

> Thanks a lot
>
> /Joe
>
>
>> -----Original Message-----
>> From: Serge Aleynikov [mailto:[hidden email]]
>> Sent: den 18 september 2006 16:45
>> To: Joe Armstrong (TN/EAB)
>> Cc: [hidden email]
>> Subject: Re: [erlang-questions] gen_tcp question
>>
>> 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.
>>
>> Regards,
>>
>> Serge
>>
>>>> -----Original Message-----
>>>> From: Jani Hakala [mailto:[hidden email]]
>>>> Sent: den 14 september 2006 15:33
>>>> To: [hidden email]
>>>> Cc: Joe Armstrong (TN/EAB)
>>>> Subject: Re: [erlang-questions] gen_tcp question
>>>>
>>>> "Joe Armstrong (TN/EAB)" <[hidden email]> 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
>>> [hidden email]
>>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>>
>>
>

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
12
Loading...