C#异步套接字BeginSend EndReceive

时间:2010-01-09 12:47:39

标签: c# sockets

我是编程新手,我对异步套接字编程感到困惑。

例如,假设我有两个BeginSend,一个接一个。第一个发送一百万个字符,第二个只发送64个字符。

由于异步性质,第二个BeginSend在第一个之前不会完成吗?

如果是这样,我怎样才能告知EndRecieve收到的数据,属于哪条消息?

2 个答案:

答案 0 :(得分:7)

你真的不应该一个接一个地调用两个BeginSend。 我认为如果发生这种情况,你最终会看到异常抛出。

你必须在调用另一个BeginSend之前调用EndSend。这通常在回调函数的一侧完成。

在MSDN上查看示例Using an Asynchronous Client Socket。在回调中调用EndSend,然后设置名为“sendDone”的ManualResetEvent。这是一种线程间通信形式,其中回调向您的主线程发信号通知异步发送已完成。然后,这允许您的程序定位下一条数据。

  • 从主线程调用BeginSend以发送前1,000,000个字节
  • 您的主线程可以检查信号量或类似ManualResetEvent的内容,以触发它发送下一个64字节。您的另一个选择是使用队列来发送数据
  • 当数据发送完毕后,将调用您传递给BeginSend的回调。
  • 在此回叫中,您将调用EndSend。然后按照此设置ManualResetEvent,或者您希望使用的线程间触发器。

我记得做过一次的最简单的选择是在第一个数据片段的回调中调用BeginSend作为下一个数据。

e.g。

int NumBytesSent; // member variable containing how many bytes you have sent so far
string Message;   // Message to send that is large

当你调用BeginSend时,传入一个100字节的大块(选择一个更大的数字以获得更高效的传输,但不能太大)来发送和增加NumBytesSend 100。 接下来,在完成上一次发送的回调中,您可以检查NumBytesSent< Message.Length,如果是,则发送Message的下一个块。

这就是你如何发送一次发送一堆字节的文件,然后继续发送文件的块直到全部发送完毕。

我强烈建议您创建一个简单的客户端/服务器,以便通过连接发送完整的文件。另请查看MSDN文档以及Web中的许多其他示例。

掌握这一点将有助于您解决许多其他C#主题,因为异步工作(或使用委托/回调)对于.NET非常常见

答案 1 :(得分:1)

BeginSend method包含参数AsyncCallback callback。如果您使用两个不同的回调,则可以看到首先完成哪个回调。

但是如果你试图在同一个连接上发送这两个消息,你就会遇到问题。您应该等到第一条消息完全发送后再发送第二条消息。