[erlang-questions] UDP client/server performance

Michael Santos michael.santos@REDACTED
Wed Aug 15 02:53:55 CEST 2012


On Tue, Aug 14, 2012 at 10:10:57PM +0200, Ronny Meeus wrote:
> Hello
> 
> thanks for the info.
> I'm currently playing with the procket and it is working well.
> 
> I have 2 questions:
> 
> - I need to run the erl as root (or use sudo to start it) or I get:
> 
> 2> {ok, FD} = procket:open(53, [{protocol, udp},{type, dgram},{family, inet}]).
> ** exception error: no match of right hand side value {error,eperm}

Make priv/procket setuid or allow your user to call priv/procket using
sudo.

> - How do I use recvfrom/4 in the server? If I call recvfrom/4 when
> there is no message present in the socket, it returns an error since
> the socket is put in async mode.

Yes, the socket has to be non-blocking or it will block the scheduler.

> Does this mean that the socket needs
> to be polled by the Erlang process or is it possible to get a
> notification (msg) when there is data present in the socket so that
> the recvfrom/4 can be called at that moment?

You could plug the fd back into gen_udp:open(Port, [{fd, FD}]) ;)

For a UDP socket, I can't think of any options other than the ones
you've mentioned: either spin on EAGAIN or use another NIF to notify you
when the socket is ready. There are a few ports to libev and libuv around.

> On Tue, Aug 14, 2012 at 11:40 AM, Michael Santos
> <michael.santos@REDACTED> wrote:
> > On Tue, Aug 14, 2012 at 08:25:23AM +0200, Ronny Meeus wrote:
> >> Is there any code available that implements a NIF to have access to UDP sockets?
> >> I have found the procket implementation but it looks like it is using
> >> a separate process to communicate with the socket. This sounds like
> >> overkill to me for this test.
> >
> > You can get the socket directly using procket:socket/3. See
> > procket:sendto/4 and procket:recvfrom/4 as well for retrieving the
> > struct sockaddr for the peer.
> >
> > -module(udp_srv).
> > -export([s/0]).
> >
> > -define(UINT16(N), N:2/native-unsigned-integer-unit:8).
> > -define(PF_INET, 2).
> > -define(PORT, 6001).
> >
> > s() ->
> >     {ok,FD} = procket:socket(inet, dgram, 0),
> >     % sockaddr for Linux
> >     Sockaddr = <<?UINT16(?PF_INET), ?PORT:16, 0:32, 0:64>>,
> >     ok = procket:bind(FD, Sockaddr),
> >     Ref = erlang:open_port({fd, FD, FD}, [stream, binary]),
> >     loop(Ref).
> >
> > loop(Ref) ->
> >     receive
> >         {Ref,{data,Data}} ->
> >             error_logger:info_report(Data),
> >             loop(Ref)
> >     end.



More information about the erlang-questions mailing list