UDP Packet Loss

323 views
Skip to first unread message

Lee Sylvester

unread,
Jul 29, 2014, 4:27:57 PM7/29/14
to elixir-l...@googlegroups.com
Hey guys,

I have a simple UDP server set up, which is experiencing packet loss.  If I send it 20 packets of 1000 bytes (1 packet each 20ms), only 16 will reach the handle_info GenServer handler.  Has anyone else experienced this?  Is there something I can do to see what's entering the message stack?

I am setting the active value of the socket to once, and reset it to once with each message.

Thanks,
Lee

Lee Sylvester

unread,
Jul 30, 2014, 4:36:09 AM7/30/14
to elixir-l...@googlegroups.com
Anyone?  I'm pulling my hair out on this one.  I've used wireshark to prove that the messages get there, and trace / statistics to analyse the message stack, but the message stack never receives those messages.

The packet loss gets worse as I increase their number.  If I send 100 packets of 1500 bytes each, one every 150ms, I get 75% packet loss.  This makes the app totally useless for streaming.

Thanks,
Lee

Alexei Sholik

unread,
Jul 30, 2014, 4:53:24 AM7/30/14
to elixir-l...@googlegroups.com
Are you using gen_udp? I would suggest asking this one on the Erlang list as there is higher likelihood to catch someone with gen_udp experience there.


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Best regards
Alexei Sholik

Paulo Almeida

unread,
Jul 30, 2014, 6:20:25 AM7/30/14
to elixir-l...@googlegroups.com
Hi,

This is my implementation of a UDP server (copied below). I haven't noticed any of the problems you mentioned. Hope it helps.

Regards,

Paulo

defmodule Transports.Udp.Server do
  require Lager
  use GenServer

  alias Transactions.Server

  def start_link(port) do
    GenServer.start_link(__MODULE__, port, [])
  end

  def init(port) do
    {:ok, socket} = :gen_udp.open(port, [:binary, {:active, false}])
    pid = spawn_link fn -> process_loop(socket) end
    :ok = :gen_udp.controlling_process(socket, pid)
    {:ok, pid}
  end

  def stop(state) do
    pid = state
    send pid, :stop
    :ok
  end

  def handle_info(_msg, state), do: { :noreply, state }
  def terminate(_reason, _state), do: :ok

  defp process_loop(socket) do
    :inet.setopts(socket, [{:active, :once}])
    receive do
      {:udp, socket, host, port, request} ->
        spawn fn ->
          ip_address = :inet_parse.ntoa(host) |> List.to_string
          Lager.debug("Received from #{ip_address}: #{inspect(request, limit: 1000)}")
          {:ok, reply} = Server.process(request, { :udp, ip_address })
          :gen_udp.send(socket, host, port, reply )
          Lager.debug("Replied to #{ip_address}: #{inspect(reply, limit: 1000)}.")
        end
        process_loop(socket)
    end
  end

end

Lee Sylvester

unread,
Jul 30, 2014, 6:27:16 AM7/30/14
to elixir-l...@googlegroups.com
Thanks, I'll give that a whirl and see if my results differ.  I'm hoping it's just a silly setting somewhere.

Cheers,
Lee

Paulo Almeida

unread,
Jul 30, 2014, 6:27:30 AM7/30/14
to elixir-l...@googlegroups.com
Also keep in mind that "IPv4 and IPv6 define minimum reassembly buffer size, the minimum datagram size that we are guaranteed any implementation must support. For IPv4, this is 576 bytes. IPv6 raises this to 1,500 bytes.". Since you're sending packets of 1500 bytes, you may receive fragmented packets.

Quarta-feira, 30 de Julho de 2014 9:36:09 UTC+1, Lee Sylvester escreveu:

Greg Young

unread,
Jul 30, 2014, 6:31:40 AM7/30/14
to elixir-l...@googlegroups.com
Basically assured of multiple packets what is the MTU of the network in question?


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Studying for the Turing test

Lee Sylvester

unread,
Jul 30, 2014, 2:59:24 PM7/30/14
to elixir-l...@googlegroups.com
Hey guys,

So, upping the values of the buffers does the trick for a single connection, but if I raise the connection, even to only 5 clients, I get packet loss again. Currently, I’m setting these flags

[{:ip, ipv4}, {:active, false}, {:buffer, 1024*1024*16}, {:recbuf, 1024*1024*16}, {:sndbuf, 1024*1024*16}, :binary]

Giving quite a hefty amount of buffer space. When I connect 5 clients to the server with an echo peer, and send about 1000 packets from each with 1500 bytes per packet, only 50% of the packets even get registered in the message stack. I’ve conferred with other Erlang devs and have heard their similar servers can support around 1000 such clients. Why, then, do I get this issue? :-(

Thanks,
Lee

On 30 Jul 2014, at 11:48, Lee Sylvester <lee.sy...@gmail.com> wrote:

> Ok, I fixed it by setting these flags for the opts.
>
> {:buffer, 2000*160}, {:recbuf, 1500*160}, {:sndbuf, 1500*160}
>
> allowing for approx 20 packets at size 1500 bytes
>
> Thanks for your help, everyone. I definitely wouldn’t have done this without some pointers from Paulo, so thanks to you, especially.
>
> Regards,
> Lee
>
>
> On 30 Jul 2014, at 11:32, Lee Sylvester <lee.sy...@gmail.com> wrote:
>
>> I’m doing this on localhost. I should not see any loss of packets at all.
>>
>> Thanks,
>> Lee

José Valim

unread,
Jul 30, 2014, 3:02:46 PM7/30/14
to elixir-l...@googlegroups.com
Have you tried it in another machine/network just to ensure you have eliminated external factors?



José Valim
Skype: jv.ptec
Founder and Lead Developer


Lee Sylvester

unread,
Jul 30, 2014, 3:04:23 PM7/30/14
to elixir-l...@googlegroups.com
Not yet.  I don’t have access to one until tomorrow.  However, using the same client with a C++ UDP server, I’m able to hit hundreds of clients, so if it is external factors, it’s Erlang / Elixir specific :-S

Lee


You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/Wu5hlpDCjyE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.

Paulo Almeida

unread,
Jul 30, 2014, 3:53:25 PM7/30/14
to elixir-l...@googlegroups.com
This thread in the "Erlang Programming" forum looks pertinent: [How to handle a massive amount of UDP packets?] https://groups.google.com/forum/#!topic/erlang-programming/dAwZ1g7BYH4
Reply all
Reply to author
Forward
0 new messages