请参阅我之前的问题,了解代码示例Sockets: sometimes (rarely) packets are lost during receiving
我需要始终从UDP多播套接字接收数据。这是单向通信我只需要监听新数据并尽快处理它。
我应该使用while(true)
吗?我不喜欢while(true)
,因为在我看来,这为处理器带来了很多额外的工作。可能c#还提供其他回拨技术吗?
答案 0 :(得分:4)
2到6个套接字(注释)可能在有趣的地方,阻塞或异步IO将正常工作,因为你没有使用线程淹没机器。每秒2000个数据包,听起来有很多东西可以保持线程忙碌。您无需担心性能视角中的while(true)
,因为Receive
方法会阻止数据可用,因此永远不会做一个无所事事的热循环。然而!就个人而言,从美容的角度来看,我同意while(true)
是一个不必要的污点,所以如果你使用阻止方法,也许可以考虑:
int bytesRead;
while((bytesRead = socket.Receive(buffer)) > 0) {
// process bytesRead from buffer
}
将在套接字关闭时干净地退出。
您也可以使用BeginReceive
和Socket.ReceiveAsync
方法执行此操作,该方法不使用阻止调用,而是使用事件或回调。这些在处理大量连接时特别有用。
就个人而言,我倾向于使用Socket.Available
;如果这是肯定的,那么有数据缓冲并准备好消耗,因此可以使用简单的Receive
来快速获取该数据而无需上下文切换。如果它为零,则当前没有当前的数据,因此异步调用可能更合适。这可以平衡上下文切换与直接调用。请注意,ReceiveAsync
方法也通过ReceiveAsync
的返回值(如果操作不完整,则为true
并且稍后将调用回调 - 并且{{} 1}}如果操作已经完成,并且将调用否回调。)
答案 1 :(得分:1)
套接字编程的最佳方法是使用它们的Async对应物。您应该调用BeginReceive并设置它的回调方法,而不是运行无限循环,该方法将在传输完成时触发。这样,您就可以保留对应用的控制权并使用更少的资源。
答案 2 :(得分:0)
异步方法是最佳解决方案。
但是在这种情况下,如果使用包含socket.Receive(buf)的while(true),则处理器没有额外的工作,因为如果没有设置超时,sockect会阻止循环直到数据到达。