udp线程优化线问题

1.一个udp客户端,在启动时,用Thread线程开一个Receive循环接收数据
2.之后,开一个Factory.Run线程,每秒一次读实时数据
3.响应用户操作,开一个线程下发

问题:运行二天后,Receive似乎一直忙于处理读实时数据,响应用户下发指令很快;但在Receive时,有时需几分钟才在Receve中处理下发返回的数据

async task  udp接收() //这里我随手从现有代码里包个方法,有些传入参数我就不写了,自己看明白了就好
{
while (!token.IsCancellationRequested)
        {
            try
            {

                using (var m = MemoryPool<byte>.Shared.Rent(65507)) //udp最大封包字节是65507,我从字节池申请一块字节来用
                {

                    IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
              //其实无需定时1s,await的意思是有数据来就收,没数据来就等着
           //也就是对方发给你了你就收,没发不理会
        //我当然不知道你们“取”的协议是啥,如果“取”是向对方发一条指令,你顶多是定时发指令,而收嘛就这里,不在定时器里
                    var r = await _socket.ReceiveFromAsync(m.Memory, SocketFlags.None, endPoint, token);
                   // _logger.LogInformation("收到-----------");
                    var buffer = m.Memory.Slice(0, r.ReceivedBytes) //你收到数据
                    var rip = r.RemoteEndPoint;//远方ip
                    var str = UTF8Encoding.ASCII.GetString(buffer.Span); //这个是打印字符串,当然你自己的协议怎么解析是另外一件事情,我这里只是如实打印
                  
                }
            }
            catch (Exception e)
            {

            }



        }
}

ps:虽然这代码我是用socket收的,不过用updclient其实是一样的代码,uppclient同样有异步接收方法ReceiveAsync
其实现在代码,我们其实不特别强调线程了。await足以
特别说明;对于网络IO来说这代码其实没有线程,并不是有 async task await就有线程。这里只是一个单纯的异步IO,你await的只是等待网卡驱动从网络接收数据(他收到了“回调”给你,或者说那是iocp完成端口异步唤起处理),而非你await一个线程处理

另外在补充一下,收了数据后怎么搞。

收到数据后,请不要做复杂的操作。对udp来说封包没有要拆包一类操作,所以大部分情况下我们认为收到一包就是一包(使用udp的大多数也不发大于上面规定的65507的数据,所以常规情况我们认为无需进行拆包操作)

所以收到数据以后请直接发布到Rx.net 或者 Channel这种生产/消费队列里。你收到了,生产了就行了
至于外面怎么消费,你不要管

在另外说一下,udp嘛无连接,偶尔丢包,偶尔乱序,偶尔延迟很正常,因为udp本身就是这样设计的。不存在tcp那种你发了,我没收到的或者你收迟了这种说法,对于使用udp的(还没有设计验证,重发,包序的)我们可以理直气壮的说“我就没收到,我就收乱了,我就收迟了”怎么拉,udp原本就如此,你任何资料任何书上都这么写的

无缓冲,数据可能冗余造成卡顿。
调Rece接收数据,将包放到一个缓冲区,然后Rece再返回接收数据。

这个问题可能出现在UDP数据包的接收与处理上。如果在Receive线程中存在一个瓶颈,可能会导致数据包积压在队列中,从而导致响应时间延迟或超时。

有几种方法可以优化这个问题:

1.优化接收循环的性能。可以检查接收数据的代码,确保其尽可能高效。例如,可以使用缓冲区来减少从套接字读取的次数。

2.增加缓冲区大小。如果接收数据的速度很快,并且处理数据的速度很慢,可以增加缓冲区的大小,以便更多的数据包可以等待处理。

3.调整线程优先级。可以将响应用户下发指令的线程的优先级提高,这样它就可以更快地响应用户请求。同时,可以降低Receive线程的优先级,以减少其对系统资源的占用。

4.对代码进行优化,避免死循环或死锁等问题,这些问题可能会导致线程无法运行或运行缓慢。

最好的方法可能是对代码进行性能测试和分析,以确定哪个部分是瓶颈,并尝试使用优化技术来改进性能。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/703118
  • 这篇博客你也可以参考下:UDP包传送字符串实现方法以及方格乱码的出现原因和解决办法
  • 除此之外, 这篇博客: (建议收藏)计算机网络:传输层概述、UDP协议与可靠传输协议习题解析与拓展中的 二.判断题(共4题,29.0分) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    1
    有时应用程序开发者更倾向于选择在UDP上运行应用程序而不是在TCP上运行,原因包括需要避免使用TCP的拥塞控制、不需要保证数据的可靠传输。

    我的答案:√
    TCP的拥塞控制和保证可靠的传输都会占用网络资源,造成信息的慢速发出。
    比如QQ,发消息用的就是UDP

    2 在今天的因特网中,当你使用视频网站提供的播放器客户端观看视频时,其语音和视频流量常常是经TCP而不是经UDP发送。

    我的答案:×
    发消息要保证速度,减少网络资源的占用,用的是UDP。

    3 在rdt协议中,接收机需要序列号来确定到达的分组是否包含新数据或是重传。

    我的答案:√
    序列号能够看出数据是否顺序正确。

    4 在rdt协议中,引人定时器来处理数据包的丢失。
    如果在定时器的持续时间内未接收到发送的分组的ACK,则假定分组(或其ACK或NACK)已经丢失,因此会重传数据包。

    我的答案:√
    rdt就是可靠数据传输协议的总称,有个时间计时器来计算到达时间是否超时,超时则做出相应的措施。


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