【问题标题】:Udp Socket stable sending, bursty receivingudp Socket 稳定发送,突发接收
【发布时间】:2011-08-01 10:20:10
【问题描述】:

我设置了一个非常简单的 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 中时,它们大约每秒 udp 触发有 1 秒延迟。接收代码似乎没有造成这种延迟,它已经在那里了。没看懂。

【问题讨论】:

  • 用wireshark (wireshark.org) 看看网络上发生了什么,贴出你的代码。
  • 消息是否按预期发送(即低延迟)?还是它们在 Wireshark 中“不稳定”?如果是,那么发送代码是错误的。如果不是,那么接收代码是错误的。
  • Wireshark 中的列表似乎也以小间隔(约 0.2 秒)更新,但我的消息在 WS 中肯定比在接收器处更流畅。发送代码也可以快速流畅地工作。但我看不出接收代码有什么问题。根本没有多少代码。
  • 再看一遍,我注意到 Wireshark 中也存在延迟。但我看不到发送代码有任何延迟。它似乎是在包裹发送后出现的。

标签: .net sockets udp datagram


【解决方案1】:

在我看来,通过使用 .Net 异步 I/O,您放弃了对发送时间的控制。我不知道这个异步设施中内置了什么样的延迟,但我的猜测是涉及到一些后台线程池并且这些线程正在轮询一些输入队列。

我会尽量避免所有这些开销,只处理在同一个线程中发送。 UDP 非常简单,只需发送和忘记,尤其是在处理单个套接字时。我认为这里不需要异步 I/O 开销。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多