【问题标题】:c# Udp BeginReceive - Messages out of orderc# Udp BeginReceive - 消息乱序
【发布时间】:2018-05-02 16:59:28
【问题描述】:

我目前正在尝试创建一个 UDP 客户端/服务器。这很简单,有一个发送函数,它发送一个字节,然后客户端立即回复一条包含我正在监听的信息的消息

我在接收数据时遇到问题。我一直收到数据,收到的包裹确实有正确的长度,但是消息似乎有问题。

SendAndReceive 函数使用 10 秒计时器。

编辑:如果我每次调用 SendAndReceive 函数时都重新创建 MyUdpClient,它可以工作,并且包的顺序没有错误。

这是我的代码:

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

字母代表解码后的消息。第一次收到这些消息时,它们是正确的,但是在那之后,消息就变得混乱了。

有什么想法吗?我不确定该采取什么方向。是线程问题还是我必须稍后解码收到的包?

感谢您的帮助和/或指导

-安德烈

【问题讨论】:

  • “邮件似乎有问题” - 这很正常,udp 不保证发送顺序。
  • 我明白,但是用wireshark检查时ip和消息是正确的。
  • 为什么这个问题被标记为async-await
  • 我的错,修好了。
  • 如果我每次调用发送和接收函数时重新创建我的 udpclient 对象,似乎一切正常。有什么想法吗?

标签: c# udp beginreceive


【解决方案1】:

我将整个实现更改为在Task 中使用.Receive 而不是.BeginReceive。我发现使用Task 会更好,因为我需要安全地停止并启动接收功能,它解决了我遇到的奇怪问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多