c # Udp BeginReceive - сообщения не в порядке - PullRequest
0 голосов
/ 02 мая 2018

В настоящее время я пытаюсь создать клиент / сервер UDP. Это довольно просто, есть функция отправки, которая отправляет байт, а затем клиенты немедленно отвечают сообщением, содержащим информацию, которую я слушаю

У меня были проблемы с получением данных. Я получаю данные все время, и полученные пакеты имеют правильную длину, однако сообщения, кажется, не в порядке.

Функция SendAndReceive находится на 10-секундном таймере.

РЕДАКТИРОВАТЬ: если я воссоздаю MyUdpClient каждый раз, когда я вызываю функцию SendAndReceive, она работает, и пакеты не в неправильном порядке.

Вот мой код:

private void SendAndReceive(object sender = null, ElapsedEventArgs e = null)
{
    ClientEndpoint = new IPEndPoint(IPAddress.Parse(IP), Port);

    // Works if i recreate MyUdpClient...
    MyUdpClient = new UdpClient();
    MyUdpClient.ExclusiveAddressUse = false;                                                                  
    MyUdpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);


    MyUdpClient.Send(InfoPacket, InfoPacket.Length, ClientEndpoint);
    try
    {
        MyUdpClient.BeginReceive(new AsyncCallback(ReceiveMessages), null);
    }
    catch (Exception exception)
    {
        Console.WriteLine($"Exception: {exception.ToString()}");
    }
}

public void ReceiveMessages(IAsyncResult res)
{
    IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, Port);
    byte[] receivedPacket = MyUdpClient.EndReceive(res, ref RemoteIpEndPoint);
    var ipAddress = RemoteIpEndPoint.Address.ToString();

    MyUdpClient.BeginReceive(new AsyncCallback(ReceiveMessages), null);

    // This is for debugging.
    string receivedTime = DateTime.Now.ToString("HH:mm:ss");
    Console.WriteLine($"[{receivedTime}]{ipAddress} {receivedPacket.Length} {Encoding.Default.GetString(receivedPacket)}");

    // Process Data Further
    ...
}

Обычно вывод выглядит примерно так:

[18.29.30]172.20.55.32 475  a
[18.29.30]172.20.55.10 455  b
[18.29.30]172.20.55.101 440 c
[18.29.30]172.20.55.17 452  d
[18.29.30]172.20.55.31 414  e
[18.29.30]172.20.55.20 449  f
[18.29.30]172.20.55.8 456   g
[18.29.30]172.20.55.28 381  h

...

[18.29.40]172.20.55.32 475  a
[18.29.40]172.20.55.10 455  b
[18.29.40]172.20.55.101 440 c
[18.29.40]172.20.55.17 452  d
[18.29.40]172.20.55.31 414  c <-- (gets cut down to 414 bytes) 
[18.29.40]172.20.55.20 449  f
[18.29.40]172.20.55.8 456   g
[18.29.40]172.20.55.28 381  h

Буквы представляют декодированные сообщения. При первом получении этих сообщений они верны, однако после этого сообщения портятся.

Есть идеи? Я не уверен, какое направление выбрать. Это проблема с многопоточностью или мне нужно декодировать полученные пакеты позже?

Спасибо за любую помощь и / или руководство

-André

1 Ответ

0 голосов
/ 04 октября 2018

Я изменил всю свою реализацию, чтобы использовать .Receive в Task вместо .BeginReceive. Я обнаружил, что использование Task лучше, потому что мне нужно было безопасно остановить и запустить функцию приема, и это устранило странную проблему, с которой я столкнулся.

...