【问题标题】:.NET Socket.BeginReceive: When is callback triggered.NET Socket.BeginReceive:什么时候触发回调
【发布时间】:2012-06-14 19:43:40
【问题描述】:

我一直想知道 BeginRecieve 调用提供的回调何时被触发。

  • 是在它接收到缓冲区可以容纳的数据时吗? 如果是这样 - 如果数据小于缓冲区怎么办)
  • 是不是收到一个 TCP/IP 包的时候?
  • 还有别的吗?

我发现了一个类似的问题,我将重复一遍,因为我不能说得更清楚:

现在所有文档都说回调,如 BeginReceive,一旦“接收到数据”就被调用。但这是 相当模糊:如果你不知道那一刻到底是什么时候 正是其他进程正在提供数据?

一个标准是 BeginReceive() 被认为已完成(因此 callbask 被调用)当状态对象中的缓冲区被填充时 达到指定的缓冲区大小。但是,如果“交付”过程是 以未知数量和不规则模式提供数据?为了 例如,如果它首先连续发送 100 个字节,然后 是 1 毫秒的时间间隔,后面还有 200 个字节:确实 BeginReceive 完成 100 字节的传入数据?还是300?

http://www.pcreview.co.uk/forums/exactly-beginreceive-socket-considered-completed-t2899270.html

【问题讨论】:

  • 我认为这取决于type of socket。当接收到数据报时,数据报套接字可能会调用回调。流套接字可能有超时、内部缓冲区等。
  • 你有没有发现这件事的真相。我正在寻求答案,而此页面上的答案似乎并不明确。 stackoverflow.com/questions/18418613/…

标签: .net sockets asynchronous


【解决方案1】:

我的经验是,任何可用的数据都需要立即调用。这意味着读取可以相当小,例如 1400 字节左右,因为这是 MTU 大小的数量级。

读取可以是它的倍数,因为如果数据包无序到达,那么在逻辑上第一个到达的那一刻,所有这些都对应用程序可见。在这种情况下,您可以一次读取所有连续排队的数据包。

我猜你的读取大小会在极快的连接上增加,因为你的应用程序可能无法像网络传递单个数据包一样快地出列字节。

旁注:BeginReceive-callback 在 Receive 返回的同时被调用。你不能以这种方式减少延迟。 (延迟实际上会增加一点点,因为异步操作可能比阻塞操作有更高的开销)。

【讨论】:

  • 对于我的场景,回调似乎没有立即调用 - 请看一下:stackoverflow.com/questions/18418613/…
  • @NielsBrinch 我没有看到证据表明这是因为异步。同步代码路径可能有同样的问题。
  • 我同意这不是因为异步。但是提问者想知道“什么时候触发回调”,并且“......它被调用以获取任何可用的数据而不会延迟”似乎不是真的
  • @NielsBrinch 在我得出结论之前,我会等着看你的问题是什么。可能存在应用程序错误或其他一些不相关的原因。一旦我们知道您的问题是什么,请随时在此处发布更新。
  • 当然,你是对的。但是,在我的问题中,我已经通过wireshark 确认包确实会逐渐到达托管服务器应用程序的服务器。
【解决方案2】:

假设您的套接字是 TCP 套接字。然后当任何数据可用时触发回调,但它在回调中传递的最大值与缓冲区大小一样多。无论如何,您都需要一个帧协议(意味着您需要多次调用 BeginReceive(..) 并检测和组装您发送的帧)。

【讨论】:

    猜你喜欢
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 2017-11-20
    • 2014-02-04
    相关资源
    最近更新 更多