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

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

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

如果是这样,我该如何在ojit_code处识别接收到的数据,属于哪一条消息?

最佳答案

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

您必须先调用EndSend,然后再调用另一个BeginSend。这通常是在回调函数旁边完成的。

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

  • 从您的主线程调用BeginSend以发送前1,000,000字节的
  • 您的主线程可以检查信号量或类似ManualResetEvent之类的信号,以触发它发送接下来的64个字节。您的另一个选择是使用数据队列发送
  • 数据发送完成后,将调用您传递给BeginSend的回调。
  • 在此回调中,您将调用EndSend。遵循此步骤,然后设置ManualResetEvent或您希望使用的任何线程间触发器。

  • 我记得曾经做过一次最简单的选择,就是对即将完成的第一个数据调用回调中的下一个数据调用BeginSend。

    例如
    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
    这就是发送文件的方式,一次发送一堆字节,然后一直发送文件块,直到全部发送完为止。

    我强烈建议您制作一个简单的客户端/服务器来执行类似通过连接发送完整文件的操作。还可以在网上查阅MSDN文档以及许多其他示例。

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

    10-04 12:15