【问题标题】:C# asynchronous socket BeginSend EndReceiveC# 异步套接字 BeginSend EndReceive
【发布时间】:2014-06-23 12:38:40
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c# sockets


    【解决方案1】:

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

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

    查看 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 中很常见

    【讨论】:

    • 感谢 Mark,这一直是我构建网络代码的方式。我已经做过很多次了,但总是从一个通用的简单起点开始,然后从那里开始。
    • 有人能解释一下他们的意思吗:它假定一个名为 connectDone 的全局 ManualResetEvent。
    • @Eidenai MSDN 站点上的示例未提供示例所需的所有成员或全局变量。在这种情况下,他们假设您在某处可访问类型为 ManualResetEvent 的变量,该变量名为 connectDone,以便他们可以使用它与 connectDone.WaitOne() 和 connectDone.Set() 进行线程间通信。这个变量需要放在两个线程都可以访问的地方
    【解决方案2】:

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

    但是,如果您尝试在同一连接上发送两条消息,则会遇到问题。您应该等到第一条消息发送完毕后再发送第二条消息。

    【讨论】:

    • 我认为发送可能会起作用,但我怀疑消息会变得交错且无法解析。
    • 那个问题。我该如何避免呢?之所以可以这样做,是因为像 mirc 这样的应用程序一直在处理这类问题。我想知道如何实现它?
    • 等到第一条消息完全发送?我应该在 EndSend 中有代码来检查第一条消息是否完成?
    • 是的。您不需要“EndSend 中的代码来检查第一条消息的完成情况”。当您收到回调时,表示发送已完成。
    • 感谢 Fuzz,您提到了一个好点。我不确定这种行为。我只是想在编码之前消除疑问。
    猜你喜欢
    • 2011-03-30
    • 2020-03-02
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 2016-09-30
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多