我应该使用while(true)从Socket接收数据吗?
请参阅我之前的问题以获取代码示例套接字:有时(很少)数据包在接收期间丢失
我需要始终从UDP多播套接字接收数据。 这是单向通信我只需要监听新数据并尽快处理它。
我应该使用while(true)
吗? 我不喜欢while(true)
因为在我看来,这为处理器带来了很多额外的工作。 可能c#提供其他回拨技术或其他什么?
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
,稍后将调用回调,如果操作已经完成,则为false
,并且不会调用任何回调)。
套接字编程的最佳方法是使用它们的Async对应程序。 您应该调用BeginReceive并设置它的回调方法,而不是运行无限循环,该方法将在传输完成时触发。 这样您就可以保留对应用的控制权并使用更少的资源。
参考: http : //msdn.microsoft.com/en-us/library/bbx2eya8.aspx#Y0
异步方法是最好的解决方案。
但是在这种情况下,如果使用包含socket.Receive(buf)的while(true),则处理器没有额外的工作,因为如果没有设置超时,sockect会阻止循环直到数据到达。