Я тестировал различные языки/методы для запуска udp-сервера, чтобы увидеть, какой из них будет самым результативным. До сих пор я тестировал .NET, NodeJs, а затем Erlang. Я вижу проблему с этим снижением кода, отбрасывающим более 50% пакетов, которые я отправляю, тогда как узлы и .net составляли ~ 4%. Сценарий заключается в том, что я отправляю 1000 20 byte messages
как можно быстрее и печатаю инкрементный номер на экран. Эрланг получает только 400 из них. Не могли бы вы предложить что-нибудь, что я мог бы сделать, чтобы улучшить этот результат?Сервер Erlang Udp, отбрасывающий множество пакетов
-module(udp).
-export([start/0]).
start() ->
spawn(fun() -> server(41235) end).
server(Port) ->
{ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
io:format("server opened socket:~p~n",[Socket]),
loop(Socket,0).
loop(Socket,N) ->
inet:setopts(Socket, [{active, once}]),
receive
{udp, Socket, Host, Port, Bin} ->
io:format("~p~n",[N]),
loop(Socket,N+1)
end.
Я бы не удивился, если полностью задержу этот код erlang. У меня было действительно трудное время, обертывающее мою голову вокруг некоторых концепций.
Мой сервер с благодарностью заимствованы из: http://erlycoder.com/83/erlang-udp-socket-usage-example-with-gen
Вот мой клиент в случае, если вы заинтересованы:
namespace LocalUdpClient
{
class Program
{
private static long _sentCount = 1;
private static CustomQueue _queue;
private static bool _continue = true;
static void Main(string[] args)
{
_queue = new CustomQueue();
_queue.ItemRemovedEventHandler += QueueOnItemRemovedEventHandler;
PopulateQueue();
var con = new System.Net.Sockets.UdpClient();
con.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 41235));
while (_continue)
{
byte[] bits = null;
if (_queue.TryDequeue(out bits))
{
con.SendAsync(bits, bits.Length);
Interlocked.Increment(ref _sentCount);
Console.Clear();
Console.Write(Interlocked.Read(ref _sentCount));
}
}
}
private static void QueueOnItemRemovedEventHandler(object sender, EventArgs eventArgs)
{
var queue = sender as CustomQueue;
if (queue.Count <= 0)
{
Task.Run(() => PopulateQueue()).Wait();
}
}
public static void PopulateQueue()
{
Console.ReadLine();
RandomNumberGenerator rand2 = new RNGCryptoServiceProvider();
Parallel.For(0, 1000, p =>
{
if (_queue.Count >= 1000) return;
byte[] bytes = new byte[20];
rand2.GetBytes(bytes);
_queue.Enqueue(bytes);
});
}
public class CustomQueue : ConcurrentQueue<byte[]>
{
public event EventHandler ItemRemovedEventHandler;
new public bool TryDequeue(out byte[] item)
{
var x = base.TryDequeue(out item);
if (ItemRemovedEventHandler != null)
{
ItemRemovedEventHandler(this,new EventArgs());
}
return x;
}
}
}
У меня ром ваш код, эта строка 'io: format (" ~ p ~ n ", [N]),' кажется, никогда не вызывается. это не выход в оболочке erlang. Не могли бы вы рассказать мне, в чем причина? – BlackMamba
Вы отправили ему пакет? Эта строка печатает только при получении пакета. – Wjdavis5