我应该使用while(true)从Socket接收数据吗?
请参考我以前的问题代码示例Sockets: sometimes (rarely) packets are lost during receiving我应该使用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
如果操作已经完整,没有回调将被调用)。
谢谢Marc。我假设我的任务(从多个UDP套接字接收多播数据)非常普遍,应该有“理想”的解决方案。这是人们需要做的事情来观看IP电视或收音机,并从我的情况下接收“证券交易所”的数据。我确定“推荐使用”的代码示例应该是某处可能甚至在MSDN的某处。也许有人可以链接这样的代码示例... – javapowered 2012-03-23 08:59:39
也可能你知道我为什么失去了pacekts :(看到我的链接问题 – javapowered 2012-03-23 09:17:51
@javapowered呃是...因为你使用UDP **,这是正常的 – 2012-03-23 09:18:35
套接字编程的最佳方式是使用它们的异步对应方法。您应该调用BeginReceive并设置它的回调方法,而不是运行无限循环,而传输完成后会触发。这样你将保持对你的应用程序的控制,并使用更少的资源。
“最佳”方式几乎总是取决于上下文中的一小部分...... – 2012-03-23 06:59:23
没有什么可以反对的。从现在开始,我的答案会更精确:) – 2012-03-23 07:03:59
异步方法是最好的解决方案。
然而,在这种情况下,如果你使用,而(真),其中包含socket.Receive(BUF)有一个为处理器没有额外的工作,因为如果你没有设置超时sockect阻止循环,直到数据到达。
你使用什么特定的呼叫来侦听新的数据包?有很多方法可以完成,而且很重要。另外:应用程序的性质是什么?它也收听了多少个广播?如果只是这一个(或几个),那么专用线程和阻塞读取调用可能不是问题。对于数十或数百或数千个连接的专用服务器,您一定要使用回调IO或Socket.Select。 – 2012-03-23 06:54:22
@MarcGravell我应该听几个套接字(从2到6),我为每个套接字使用专用线程。我在每个套接字上每秒接收约2000个数据包 – javapowered 2012-03-23 06:58:50