[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