[erlang-questions] Problems with sending UDP datagrams without buffering

Matthias Lang <>
Wed Oct 29 21:52:31 CET 2008


On Wednesday, October 29, Mark Geib wrote:

> Yes, I am using UDP, not TCP. And to confirm, I am sending 700 bytes,
> never any more. I see the 7000 byte datagram in WireShark on another
> system monitoring the network. The 7000 bytes are reported as fragmented
> packets that have been re-assembled. I am an sending the 700 bytes every
> 20 miliseconds.

> I am assuming that erlang is buffering in a lower layer, but could be
> the linux network stack as well.

If either of those two assumptions were true, then erlang (or linux)
would break pretty much every UDP protocol there was. Everyone with
a SIP stack would be screaming blue murder. They're not, so those 
assumptions look unlikely.

Here's a minimal program which does what you say you're doing:

-module(udpsender).
-export([go/1]).

go(Length) when is_integer(Length), Length > 0, Length < 16#ffff ->
    {ok, S} = gen_udp:open(0),
    {ok, Portno} = inet:port(S),
    io:fwrite("using outgoing port #~p\n", [Portno]),
    Bin = list_to_binary(lists:duplicate(Length, 36)),
    loop(S, Bin).

loop(S, Bin) ->
    gen_udp:send(S, {172,16,2,7}, 9999, Bin),
    timer:sleep(20),
    loop(S, Bin).

If I watch the network interface with 'tcpdump port 9999', here's what
udpsender:go(700) looks like:

21:36:10.081265 IP contorpis.53829 > gth21.9999: UDP, length 700
21:36:10.102115 IP contorpis.53829 > gth21.9999: UDP, length 700
21:36:10.125267 IP contorpis.53829 > gth21.9999: UDP, length 700
21:36:10.146114 IP contorpis.53829 > gth21.9999: UDP, length 700
21:36:10.169257 IP contorpis.53829 > gth21.9999: UDP, length 700
21:36:10.190114 IP contorpis.53829 > gth21.9999: UDP, length 700
21:36:10.213255 IP contorpis.53829 > gth21.9999: UDP, length 700

i.e. as expected. One IP packet per UDP payload, length is always 700.
I let it run for a minute while writing this. All lengths 700.

Repeating for udpsender:go(7000), I get

21:39:40.726132 IP contorpis.43227 > gth21.9999: UDP, length 7000
21:39:40.749771 IP contorpis.43227 > gth21.9999: UDP, length 7000
21:39:40.770129 IP contorpis.43227 > gth21.9999: UDP, length 7000
21:39:40.793768 IP contorpis.43227 > gth21.9999: UDP, length 7000
21:39:40.814133 IP contorpis.43227 > gth21.9999: UDP, length 7000

i.e. again as expected. You can see the fragments by removing the port
filter:

21:41:36.329803 IP contorpis.43227 > gth21.9999: UDP, length 7000
21:41:36.329818 IP contorpis > gth21: udp
21:41:36.329826 IP contorpis > gth21: udp
21:41:36.329831 IP contorpis > gth21: udp
21:41:36.329836 IP contorpis > gth21: udp

So: the behaviour you're reporting is unexpected and I can't reproduce
it. One way to make some progress is to post a minimal program which
demonstrates what you're seeing so that others can try and repeat it.

Matt

p.s. all of the above is on R12B-4, Linux 2.6.24-1-amd64 and erlang
says "version 5.6.4 [source] [64-bit] [smp:2] [async-threads:0] [hipe]
[kernel-poll:false]" at startup



More information about the erlang-questions mailing list