我应该使用while(true)从Socket接收数据吗?

时间:2012-03-23 06:49:50

标签: c# sockets

请参阅我之前的问题,了解代码示例Sockets: sometimes (rarely) packets are lost during receiving

我需要始终从UDP多播套接字接收数据。这是单向通信我只需要监听新数据并尽快处理它。

我应该使用while(true)吗?我不喜欢while(true),因为在我看来,这为处理器带来了很多额外的工作。可能c#还提供其他回拨技术吗?

3 个答案:

答案 0 :(得分:4)

2到6个套接字(注释)可能在有趣的地方,阻塞或异步IO将正常工作,因为你没有使用线程淹没机器。每秒2000个数据包,听起来有很多东西可以保持线程忙碌。您无需担心性能视角中的while(true),因为Receive方法会阻止数据可用,因此永远不会做一个无所事事的热循环。然而!就个人而言,从美容的角度来看,我同意while(true)是一个不必要的污点,所以如果你使用阻止方法,也许可以考虑:

int bytesRead;
while((bytesRead = socket.Receive(buffer)) > 0) {
    // process bytesRead from buffer
}

将在套接字关闭时干净地退出。

也可以使用BeginReceiveSocket.ReceiveAsync方法执行此操作,该方法不使用阻止调用,而是使用事件或回调。这些在处理大量连接时特别有用。

就个人而言,我倾向于使用Socket.Available;如果这是肯定的,那么有数据缓冲并准备好消耗,因此可以使用简单的Receive来快速获取该数据而无需上下文切换。如果它为零,则当前没有当前的数据,因此异步调用可能更合适。这可以平衡上下文切换与直接调用。请注意,ReceiveAsync方法也通过ReceiveAsync的返回值(如果操作不完整,则为true并且稍后将调用回调 - 并且{{} 1}}如果操作已经完成,并且将调用回调。)

答案 1 :(得分:1)

套接字编程的最佳方法是使用它们的Async对应物。您应该调用BeginReceive并设置它的回调方法,而不是运行无限循环,该方法将在传输完成时触发。这样,您就可以保留对应用的控制权并使用更少的资源。

参考:http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx#Y0

答案 2 :(得分:0)

异步方法是最佳解决方案。

但是在这种情况下,如果使用包含socket.Receive(buf)的while(true),则处理器没有额外的工作,因为如果没有设置超时,sockect会阻止循环直到数据到达。