【发布时间】:2015-01-12 18:05:15
【问题描述】:
我正在尝试向不同的远程主机发送 许多 小(约 350 字节)UDP 消息,每个远程主机一个数据包。我正在使用后台线程来监听响应
private void ReceivePackets()
{
while (true)
{
try
{
receiveFrom = new IPEndPoint(IPAddress.Any, localPort);
byte[] data = udpClientReceive.Receive(ref receiveFrom);
// Decode message & short calculation
}
catch (Exception ex)
{
Log("Error receiving data: " + ex.ToString());
}
}
}
和一个用于发送消息的主线程
udpClientSend.SendAsync(send_buffer, send_buffer.Length, destinationIPEP);
UdpClient udpClientReceive 和 UdpClient udpClientSend 都绑定到同一个端口。
问题是SendAsync() 大约需要 15 毫秒才能完成,我需要每秒发送几千个数据包。我已经尝试过使用udpClientSend.Send(send_buffer, send_buffer.Length, destination);,它同样慢。我还将接收/发送缓冲区设置得更高,我尝试设置udpClientSend.Client.SendTimeout = 1;,但没有效果。我怀疑这可能与远程主机更改每个数据包有关?如果是这样的话,在单独的线程中使用多个 UDPclient 会不会让事情变得更快?
感谢您的帮助!
注意事项: 网络带宽不是问题,我需要使用 UDP 而不是 TCP。 我在这个网站上看到过类似的问题,但没有一个令人满意的答案。
编辑
只有一个线程用于发送,它运行一个简单的循环,其中调用udpClientSend.SendAsync()。
我正在查询 DHT(bittorrent 哈希表)中的节点,因此多播不是一个选项(?) - 每个主机只能获得 1 个数据包。
将UDPClient 类与Socket 类交换并使用AsyncSendTo() 不会加快速度(或微不足道)。
我已经缩小了问题范围:将远程主机地址更改为某个固定 IP 和端口可将吞吐量提高到超过 3000 个数据包/秒。因此,过于频繁地更改目标地址似乎是瓶颈。
我认为我的问题可能与 UDP "Connect"-Speed in C# 和 UDPClient.Connect() 正在减慢代码速度有关。如果是这样,是否有解决此问题的方法?是语言问题还是操作系统问题?
【问题讨论】:
-
我对这些方法的性能了解不多,但提到 15ms 可能会引发问题。如果您使用诸如 GetTickCount() 之类的方法来计时,该时钟的分辨率约为 15 毫秒,并且不准确地测量延迟可能会让您寻找错误的解决方案。
-
我在
UdpClient或Socket中看不到任何会导致性能下降的内容。凯蒂的解释似乎很有可能。 -
你每秒测量多少个数据包?
-
另外,我不能代表
UdpClient,但是当使用裸机方法Socket.SendToAsync时,您可以有多个未完成的发送——这将为您提供最大的吞吐量。 -
我正在使用 Stopwatch 类来测量时间。 15ms 是平均值,大多数消息花费的时间更少,但至少需要 3ms。 Wireshark 测量大约 200 个数据包/秒,其中只有一半是上游的。这似乎大致对应于 15ms 的数字。 @Cory Nelson:我不确定我是否理解正确,您是否建议使用额外的线程来并行调用 Socket.SendAsync()?
标签: c# performance udp