C#UDP发送/发送异步太慢

C#UDP发送/发送异步太慢,c#,performance,udp,C#,Performance,Udp,我正在尝试向不同的远程主机发送许多小型(~350字节)UDP消息,每个远程主机一个数据包。我正在使用一个背景线程来听取回应 private void ReceivePackets() { while (true) { try { receiveFrom = new IPEndPoint(IPAddress.Any, localPort); byte[]

我正在尝试向不同的远程主机发送许多小型(~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\u buffer,Send\u buffer.Length,destination)同样慢。我还将接收/发送缓冲区设置得更高,并尝试将
udpClientSend.Client.SendTimeout=1无效。我怀疑这可能与每一个数据包的远程主机改变有关?如果是这样的话,在单独的线程中使用多个UDPClient会使事情更快吗?
谢谢你的帮助

注: 网络带宽不是问题,我需要使用UDP而不是TCP。 我在这个网站上看到过类似的问题,但都没有令人满意的答案

编辑

只有一个用于发送的线程,它运行一个简单的循环,在该循环中调用
udpClientSend.sendsync()

我正在查询DHT(bittorrent哈希表)中的节点,因此多播不是一个选项(?)-每个主机只获得一个数据包。
使用
Socket
类交换
UDPClient
类,并使用
AsyncSendTo()
并不会加快速度(或者说没有什么意义)

我已经缩小了问题的范围:将远程主机地址更改为某个固定的IP和端口会将吞吐量提高到3000多个数据包/秒。因此,过于频繁地更改目标地址似乎是瓶颈


我想我的问题可能与UDPClient.Connect()有关,
UDPClient.Connect()
正在减慢代码的速度。如果是这样,是否有解决方案?这是语言问题还是操作系统问题

为什么在发送之前要使用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());
var端口=4242;
var ipEndPoint1=新的IPEndPoint(IPAddress.Parse(“192.168.56.101”),端口);
var ipEndPoint2=新的IPEndPoint(IPAddress.Parse(“192.168.56.102”),端口);
var buff=新字节[350];
var client=new UdpClient();
整数计数=0;
var stopWatch=新秒表();
秒表。开始();
同时(计数<3000)
{
IPEndPoint端点=ipEndPoint1;
如果((计数%2)=0)
端点=ipEndPoint2;
发送(buff,buff.Length,endpoint);
计数++;
}
秒表;
WriteLine(“RunTime”+stopWatch.appeased.totalmillizes.ToString());

我对这些方法的性能不太了解,但提到15毫秒可能会引发一个问题。如果您使用GetTickCount()之类的工具对此计时,则时钟的分辨率约为15毫秒,并且不准确地测量延迟可能会使您在错误的路径中搜索解决方案。我在
UdpClient
Socket
中没有看到任何会导致性能低下的内容。Katie的解释似乎最有可能。你测量每秒多少个数据包?另外,我不能代表
UdpClient
,但是当使用裸机方法
Socket时,你可以有多个未完成的发送。SendToAsync
——这将给你最大的吞吐量。我使用秒表类来测量时间。15毫秒是平均值,大多数消息花费的时间较少,但至少3毫秒。Wireshark每秒测量约200个数据包,其中只有一半在上游。这似乎大致相当于15毫秒的数值。@Cory Nelson:我不确定我是否理解正确,您是否建议使用其他线程来并行调用Socket.SendAsync()?