Udp Socket стабильная отправка, пакетный прием - PullRequest
0 голосов
/ 01 августа 2011

Я настроил очень простой UdpClient для получения 8 байтов данных как можно быстрее. Клиент отправляет данные очень быстро, но сервер получает их с очень прерывистыми интервалами, примерно 0,5 секунды. Он останавливается при получении, а затем внезапно очень быстро получает около десяти дейтаграмм подряд, затем снова останавливается на ~ 0,5 секунды и так далее. В чем может быть проблема здесь? Я пытался отключить брандмауэр, но это не помогло ...

Клиент:

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

Этот код постоянно отправляет накопленный буфер:

if (!_sending)
{
    _sending = true;

    SocketAsyncEventArgs args = new SocketAsyncEventArgs();

    args.Completed += (s2, e2) => { _sending = false; };
    args.RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123);
    args.SetBuffer(buffer, 0, buffer.Length);

    _socket.SendToAsync(args);
}

Сервер:

    UdpClient udp = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 14123));
    IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);

    while (true)
    {
        byte[] buffer = udp.Receive(ref endpoint);
        int x = BitConverter.ToInt32(buffer, 0);
        int y = BitConverter.ToInt32(buffer, 4);
        Console.WriteLine(string.Format("Receiving x={0}, y={1} @ {2}", x, y, DateTime.Now.Ticks));
    }

Я знаю его очень примитивный код прямо сейчас, но, по крайней мере, он не выдает никаких исключений ...

Я проверил с Wireshark, но я не уверен, что именно искать. UDP-сообщения отправляются нормально, без сбоев.

Я прочитал, что неплохо бы настроить UDP и не отправлять его так быстро, как это возможно. Я попробовал это без какой-либо заметной разницы. Отправка идет медленнее, но прием такой же громоздкий, как и раньше.

Клиент и получатель находятся на одном компьютере разработчика (Windows 7).


Вот некоторые результаты измерения времени (-ов) между приемом-вызовом. Как вы можете видеть, он застревает на одну секунду примерно каждые 30 итераций:

1,0180582
0,001
0
0
0,0010001
0
0
0
0
0,0010001
0
0
0
0
0
0
0
0
0
0
0,0010001
0
0
0
0
0
0,0010001
1,0170582

и т.д.

Обновление

Похоже, задержка возникает после отправки буферов. Код отправки, кажется, отправляет буферы очень быстро / плавно, но когда они появляются в Wireshark, они имеют задержку в 1 секунду примерно каждую секунду срабатывания udp. Кажется, что получающий код не вызывает эту задержку, он уже есть. Я не понимаю.

1 Ответ

1 голос
/ 05 августа 2011

Мне кажется, что с помощью асинхронного ввода-вывода .Net вы отказываетесь от контроля времени отправки. Я не знаю, какие задержки встроены в эту асинхронную программу, но я предполагаю, что задействован некоторый фоновый пул потоков, и эти потоки опрашивают некоторую очередь ввода.

Я бы постарался избежать всех этих издержек и просто занялся бы отправкой в ​​том же потоке. UDP очень прост, просто отправляйте и забывайте, особенно когда речь идет об одном сокете. Я не думаю, что здесь требуется асинхронный ввод-вывод.

...