我是编程新手,对异步套接字编程感到困惑。
例如,假设我有两个 BeginSend
,一个接一个。第一个发送一百万个字符,第二个仅发送 64 个字符。
由于异步性质,第二个 BeginSend
不会在第一个之前完成吗?
如果是这样,我如何判断在EndRecieve
接收到的数据属于哪条消息?
最佳答案
您真的不应该一个接一个地调用两个 BeginSend。 如果发生这种情况,我认为您最终会看到抛出的异常。
您必须在调用另一个 BeginSend 之前调用 EndSend。这通常在回调函数中完成。
查看示例 Using an Asynchronous Client Socket在 MSDN。在回调中调用 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 字节的 block (选择一个更大的数字以获得更高效的传输,但不要太大)以发送并将 NumBytesSend 递增 100。 接下来,在上一个发送完成的回调中,您可以检查 NumBytesSent < Message.Length,如果是,则发送消息的下一个 block 。
这就是您发送文件的方式,一次发送一堆字节,然后继续发送文件 block ,直到全部发送完毕。
我强烈建议做一个简单的客户端/服务器来做一些事情,比如通过连接发送一个完整的文件。另请查看 MSDN 文档和网络上出现的许多其他示例。
很好地掌握这一点将帮助您处理许多其他 C# 主题,因为异步工作(或使用委托(delegate)/回调)在 .NET 中很常见
关于C# 异步套接字 BeginSend EndReceive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2033402/