正确使用BeginReceive / EndReceive?

时间:2014-11-07 17:03:26

标签: c# sockets

从套接字异步接收数据.Net支持对称的BeginReceive / EndReceive调用。基本上你调用BeginReceive()来开始监听并识别应该在数据到达时调用的回调。在回调内部,您调用EndReceive()来提取数据并结束异步读取操作。

我正在编写C#/。Net软件来控制一些工业设备。控制面板允许用户设置和初始化设备,并且一旦初始化BeginReceive()被称为开始侦听数据。在回调中EndReceive()用于提取数据,但我想立即继续收听,因此我认为应该在执行BeginReceive()之后再次调用EndReceive()。这是对的吗?

如果是,我是否可以在代码中的其他位置使用检查或测试来了解是否已调用BeginReceive(),因此我不会尝试连续两次调用BeginReceive()EndReceive()被调用之前,在同一个套接字上?

2 个答案:

答案 0 :(得分:6)

在拨打BeginReceive()之前,您无法再次呼叫EndReceive()的方法是将BeginReceive()的呼叫置于您呼叫EndReceive()的完成回叫中。当然,唯一不应在BeginReceive()执行的调用是在Socket连接后立即执行的调用。

编辑:

要明确:在任何接收完成发生之前,允许多次呼叫BeginReceive()。但是当你这样做时,你需要确保你做了必要的内务管理,以确保你按照正确的顺序处理数据(即你按照BeginReceive()提交缓冲区的顺序处理缓冲区。) / p>

所以上面的答案是不必完成所有的内务管理,从而使代码更简单。

如果您只是在调用BeginReceive()的同一地点对EndReceive()进行后续调用,那么保持秩序是微不足道的。请注意,您仍然需要这样做:确保始终以正确的顺序接收缓冲区的最简单方法是,在之后之后再调用BeginReceive() EndReceive()(但仍使用相同的方法)。

答案 1 :(得分:2)

是的,您需要在收到数据后致电BeginReceive,以便在数据可用时获得更多信息。

由您来处理Socket的状态,而不是两次调用BeginReceive。有些属性可以让您知道数据是否可用,但没有任何信息可以告诉您是否已经在等待接收数据。

Socket的大多数实现最终成为另一个具有此逻辑的包装类,以便在第二次调用时忽略BeginReceiveSocket类有时很痛苦,因为你不能在没有关闭的情况下取消BeginReceive