关于#udp接收处理数据慢##C#

更新:现在是感觉udp发送的代码太碎了,就是说发送过来的数据就是几字节一帧就发过来了,导致接够能进行处理的整包数据需要接收很多次,然后导致整个系统的延迟。
一段同样的程序 在四台电脑上运行正常 在一台平板手持电脑上运行特别慢 四台电脑都比这个平板电脑配置低 平板电脑32G内存 I7 7500u 2.9GCPU有解惑的吗?
程序是用C#写,开了两个后台线程,一个线程udp同步接收数据并放入一个缓存,另一个线程处理数据。下面是代码

 udpTeleReceiver = new UdpClient(int.Parse(PortTeleRece));
 udpTeleSenderEndPoint = new IPEndPoint(IPAddress.Parse(stringIpInfo), int.Parse(PortTeleRece));

               if (threadRecvTeleData == null)
                {
                    threadRecvTeleData = new Thread(delegate() { RevTeleDataMethod(); });
                    threadRecvTeleData.Start();
                    threadRecvTeleData.IsBackground = true;
                }

                if (threadHandleRecvTeleData == null)
                {
                    threadHandleRecvTeleData = new Thread(delegate() { RevTeleDataHandleMethod(); });
                    threadHandleRecvTeleData.Start();
                    threadHandleRecvTeleData.IsBackground = true;
                }

        private void RevTeleDataMethod()
        {
            while (true)
            {
                Thread.Sleep(1);
                try
                {
                    byte[] btTeleData = udpTeleReceiver.Receive(ref udpTeleSenderEndPoint);
                    if (btTeleData.Length >0)
                    {
                        if (btTeleData[6] == 0x15 && btTeleData[7] == 0x07)
                        {
                            
                        }
                        else
                        {
                            Uav_Data.isNewData = true;
                            Uav_Data.tickCount = 0;
                           
                            //添加加入list代码
                            lstRecBuffDataTemp.AddRange(btTeleData);
                        }

                }
                }
                catch (Exception ex)
                {
                }
                continue;
            }
        }

        private void RevTeleDataHandleMethod()
        {
            while (true)
            {
              Thread.Sleep(1);
                      //大于134个字节开始处理
                while (lstRecBuffDataTemp.Count >= 134)
                {
                    try
                    {
                        int intdexFindA5 = lstRecBuffDataTemp.IndexOf(0xEB);
                        int indexFindA5Second = lstRecBuffDataTemp.IndexOf(0xEB, intdexFindA5+1);
                        int indexFindA5Third = lstRecBuffDataTemp.IndexOf(0xEB, indexFindA5Second + 1);
                        if (lstRecBuffDataTemp[intdexFindA5 + 1] == 0x90 )
                        {
                            int lengthRecBuffData = lstRecBuffDataTemp[intdexFindA5 + 2 + 6] + 6;
                            Uav_Data.strUavInfo.FlyNum = lstRecBuffDataTemp.Count;
                            byte[] bttempRecTeledata = new byte[lengthRecBuffData];
                            lstRecBuffDataTemp.CopyTo(intdexFindA5, bttempRecTeledata, 0, lengthRecBuffData);
                            byte[] btreceivedWrite = new byte[lengthRecBuffData + 9];
                            btreceivedWrite[0] = (byte)(lengthRecBuffData + 9);
                            Buffer.BlockCopy(BitConverter.GetBytes(DateTime.Now.Ticks), 0, btreceivedWrite, 1, 8);//添加时间戳进行文件记录
                            Buffer.BlockCopy(bttempRecTeledata, 0, btreceivedWrite, 9, lengthRecBuffData);
                            GCSFileTool.FileWriter.StreamWriteFunc(btreceivedWrite);
                            ResolutionSourceData(bttempRecTeledata, lengthRecBuffData);
                            if (NetDisPlayForm.isDisPlayRemoteData)
                            {
                                EventRemoteData(bttempRecTeledata);
                            }
                            lstRecBuffDataTemp.RemoveRange(0, intdexFindA5 + lengthRecBuffData);
                        }
                        else
                        {
                            lstRecBuffDataTemp.RemoveRange(0, intdexFindA5 + 1);
                            continue;
                        }

                    }
                    catch (Exception)
                    {
                        lstRecBuffDataTemp.RemoveRange(0, 134);
                    }

                }

            }
        }
UdpClient client = new UdpClient(3381);

Task.Run(async () =>
{
    while (true)
    {
        //请直接使用异步,不要使用某园子的“高级sleep”
        //这个就是你接收的结果
        var udppackge = await client.ReceiveAsync();
        //buffer就是数据包
        var buffer = udppackge.Buffer;
        //这个是远程ip
        var rip = udppackge.RemoteEndPoint;

        //udp不存在粘包无需在跟某园子学啥list分析了,下面请直接使用
        //我这里用span传递,只是不想重新分配内存
        //如果框架版本低,直接用 byte[]也行
        ProcessMsg(buffer.AsSpan());


    }
});
Task ProcessMsg(Span<byte> data)
{
    //把data重新在栈内分配一个变量,避免闭包穿越
    var _data=data;
   
    return Task.Run(() =>
    {
        //这里分析数据是否你想要的
       // if(_data is xxxxx)
        //如果是你想要的,你用事件传递还是用消息队列传递
        //就随便你了

    });

}

看看是不是网络的问题。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/195396
  • 以下回答来自chatgpt:

    首先,需要确认问题是出在UDP接收数据过慢上还是数据处理速度上。可以通过测试不使用后台线程,只在主线程中接收数据,看看是否有更快的速度。

    如果问题出在UDP接收数据速度上,可以尝试以下几步优化:

    1. 设置ReceiveBufferSize 可以通过设置UDP Socket的ReceiveBufferSize属性来增加接收缓存大小,从而提高接收数据的速度。比如:
    UdpClient udpClient = new UdpClient(port);
    udpClient.Client.ReceiveBufferSize = 1024 * 1024; // 设置缓存大小为1MB
    
    1. 开启并行处理 可以使用并行处理,开启多个线程同时接收数据,从而提高接收数据的速度。比如:
    var tasks = new List<Task>();
    
    for (int i=0; i<numberOfThreads; i++)
    {
        var task = Task.Run(() => ReceiveData(udpClient));
        tasks.Add(task);
    }
    
    await Task.WhenAll(tasks);
    
    1. 使用异步接收数据 可以使用异步接收数据,提高接收和处理数据的效率。比如:
    private async Task ReceiveData(UdpClient udpClient)
    {
        while (true)
        {
            var result = await udpClient.ReceiveAsync();
            var buffer = result.Buffer;
            // 处理数据
        }
    }
    

    如果问题出在数据处理速度上,可以尝试以下几步优化:

    1. 使用线程池 可以使用线程池来处理数据,从而更好地利用计算资源。比如:
    ThreadPool.QueueUserWorkItem(ProcessData, data);
    
    1. 检查代码逻辑 可能存在数据处理批处理不足,处理方法不够优化等问题。可以检查代码逻辑,进行优化。

    总之,需要先确定问题在哪里,然后针对性地进行优化。同时,在进行优化时,需要兼顾效率和稳定性,避免因优化而引入新的问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^