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.对代码进行优化,避免死循环或死锁等问题,这些问题可能会导致线程无法运行或运行缓慢。
最好的方法可能是对代码进行性能测试和分析,以确定哪个部分是瓶颈,并尝试使用优化技术来改进性能。
不知道你这个问题是否已经解决, 如果还没有解决的话:1
有时应用程序开发者更倾向于选择在UDP上运行应用程序而不是在TCP上运行,原因包括需要避免使用TCP的拥塞控制、不需要保证数据的可靠传输。
我的答案:√
TCP的拥塞控制和保证可靠的传输都会占用网络资源,造成信息的慢速发出。
比如QQ,发消息用的就是UDP
2 在今天的因特网中,当你使用视频网站提供的播放器客户端观看视频时,其语音和视频流量常常是经TCP而不是经UDP发送。
我的答案:×
发消息要保证速度,减少网络资源的占用,用的是UDP。
3 在rdt协议中,接收机需要序列号来确定到达的分组是否包含新数据或是重传。
我的答案:√
序列号能够看出数据是否顺序正确。
4 在rdt协议中,引人定时器来处理数据包的丢失。
如果在定时器的持续时间内未接收到发送的分组的ACK,则假定分组(或其ACK或NACK)已经丢失,因此会重传数据包。
我的答案:√
rdt就是可靠数据传输协议的总称,有个时间计时器来计算到达时间是否超时,超时则做出相应的措施。