我正在尝试将许多小(~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;
无效。我怀疑它可能与远程主机改变每个数据包有关吗?如果是这种情况,在单独的线程中使用多个UDP客户端会使事情变得更快吗?
谢谢你的帮助!
注意: 网络带宽不是问题,我需要使用UDP而不是TCP。 我在这个网站上看到过类似的问题,但没有一个令人满意的答案。
修改
只有一个发送线程,它运行一个简单的循环,其中调用udpClientSend.SendAsync()
我正在查询DHT(bittorrent散列表)中的节点,因此多播不是一个选项(?) - 每个主机只获得1个数据包。
与UDPClient
类交换Socket
类并使用AsyncSendTo()
不会加快速度(或微不足道)。
我已经缩小了问题:将远程主机地址更改为某些固定IP&端口将吞吐量提高到超过3000个数据包/秒。因此,经常更改目标地址似乎是瓶颈。
我认为我的问题可能与UDP "Connect"-Speed in C#有关,UDPClient.Connect()
正在减慢代码速度。如果是这样,有没有解决这个问题?它是语言还是操作系统问题?
答案 0 :(得分:0)
为什么在发送之前使用UdpClient Connect?如果要设置默认主机,这是可选步骤。看起来您想要发送到多个目的地,这样您就可以在每次调用Send方法时设置远程主机。
如果你决定删除Connect方法,你可能会看到一个改进,但看起来你的代码中的其他地方仍然存在瓶颈。隔离发送呼叫和测量时间,然后开始添加更多步骤,直到找到减慢速度的步骤。
var port = 4242;
var ipEndPoint1 = new IPEndPoint(IPAddress.Parse("192.168.56.101"), port);
var ipEndPoint2 = new IPEndPoint(IPAddress.Parse("192.168.56.102"), port);
var buff = new byte[350];
var client = new UdpClient();
int count = 0;
var stopWatch = new Stopwatch();
stopWatch.Start();
while (count < 3000)
{
IPEndPoint endpoint = ipEndPoint1;
if ((count % 2) == 0)
endpoint = ipEndPoint2;
client.Send(buff, buff.Length, endpoint);
count++;
}
stopWatch.Stop();
Console.WriteLine("RunTime " + stopWatch.Elapsed.TotalMilliseconds.ToString());