【问题标题】:Socket ReceiveAsync merging packetsSocket ReceiveAsync 合并数据包
【发布时间】:2011-10-11 02:03:40
【问题描述】:

我打算通过套接字接收数据包,但由于它们是从发送者以高频率发送的,因此它们中的一些被打包到单个 byte 数组中。 SocketAsyncEventArgs.Buffer 然后保存多个数据包,即使它们是单独发送的(使用wireshark 验证)。

我已经尝试对传入的数据包进行排队并异步处理它们,但我仍然得到相同的结果。

这种行为可能是什么原因?

【问题讨论】:

    标签: c# .net sockets asynchronous tcp


    【解决方案1】:

    我可能弄错了,但这不是 Naggle 算法的作用吗? 您的套接字应该有一个禁用此功能的标志。

    【讨论】:

    • 不,不是。 TCP是一个流。期望接收介于 1 字节和所提供缓冲区大小的最小值之间的任何值,以及每次读取时未完成的字节数。数据是通过一个或多个发送调用发送的都没有关系。禁用 nagle 将无济于事;虽然它可能看起来有帮助。 (-1)
    【解决方案2】:

    这就是 TCP 的工作原理。 TCP 连接是一个双向字节流,你必须这样对待它。来自一端的单次发送可能会导致接收端进行多次读取,反之亦然,多次发送可能会以单次读取结束,并且传输不会保留应用程序消息边界。

    您必须缓冲输入,直到您知道您有完整的应用程序消息。常见的方法有:

    • 固定长度消息,
    • 消息前面的前置长度,
    • 使用特殊的“消息结束”分隔符分隔流。

    【讨论】:

    • 正是这样,TCP 是一个流协议(字节流 - 不是数据包 - 由应用程序使用)。 UDP是一种数据报协议(离散包)
    • 我使用的协议是使用换行符结尾作为分隔符。而且,有些消息的数据中有换行符 - 我应该如何区分它们?
    • 嗯,尝试一些不可打印的字符,如 \001(FIX 字段分隔符)或其他不在数据中的字符来分隔消息。
    • 协议不是我自己制定的。我必须对此做出反应:/
    • 在流协议上使用的协议,例如 TCP,需要某种方式来唯一标识消息限制。通过唯一字符/序列或通过消息头中的长度字段。如果它们都不存在,则协议存在缺陷,无法可靠接收。
    猜你喜欢
    • 2019-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 2015-11-22
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2017-05-15
    相关资源
    最近更新 更多