[erlang-questions] UDP client/server performance

Ronny Meeus ronny.meeus@REDACTED
Wed Aug 15 09:59:22 CEST 2012


On Wed, Aug 15, 2012 at 2:53 AM, Michael Santos
<michael.santos@REDACTED> wrote:
> 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.

I tried all options mentioned in your readme already before but non of
them seem to work on Ubuntu. I think there is an issue with the sudo
stuff on this distribution since no matter what I do, it always ask
for a password when the procket command is executed.

Now I succeeded by explicitly specifying the name of the program to use:
procket:open(53, [{progname,"/usr/local/bin/procket"},{protocol,
udp},{type,dgram}]).

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

OK I will look around.
Thanks.

Yesterday I did a quick test and created an application that once it
receives a message, it starts to send this back in a loop.
It looks like it is able to send almost 200Kpkts/sec on a low end PC
while the gen_udp solution only was able to send something like
10Kpks/sec on a much more powerful PC. So it looks promising ...

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