C# 异步套接字 BeginSend EndReceive

标签 c# sockets

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

例如,假设我有两个 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/

相关文章:

c++ - C++中的多线程,从套接字接收消息

java - Java socket编程中如何实现客户端到服务器的持续交互

sockets - 如何使用 std.socket 和 std.socketstream? (D 编程语言 2.x)

c# - Linq-to-SQL 的三元运算符导致问题?

c# - 对定义为无符号字节位范围的数字执行有符号算术

c# - CsvHelper:用另一个表达式替换缺失的 Csv 字段?

c# - 如何使用 Dateformat ISO 8601 创建 .NET CultureInfo?

c# - 您将如何使用 Scala 的异步使多个异步请求超时?

java - 如何: Java Server Socket response and Client reading

python - 两个不同的远程服务器使用python进行通信