【问题标题】:How to gather received buffers in socket programming (TCP/IP) in .net?如何在.net 中的套接字编程(TCP/IP)中收集接收到的缓冲区?
【发布时间】:2012-09-14 22:08:13
【问题描述】:

我正在使用服务器-客户端模型通过套接字编程与硬件板进行通信。

我使用“NetworkStream”类的“read()”方法从板上接收数据,该方法读取具有指定最大大小的缓冲区并返回缓冲区中有效数据的长度。我已经考虑了足够大的缓冲区的最大大小。

董事会每 100 毫秒发送一组消息。每条消息都包含一个 2 字节的常量标头和可变数量的字节作为其在标头字节之后的数据。

问题是我没有收到一条一条的消息!相反,我收到的缓冲区可能包含 2 或 3 条消息,或者一条消息分散在两个缓冲区之间。

目前,我正在使用 DFA,它使用恒定的标头字节收集消息的内容(我们不知道消息的长度,我们只知道标头字节)但问题是数据字节可能包含标头随机字节!!

是否有任何有效的方法可以使用任何特定的流或类从缓冲区中收集每条消息的字节?我该如何克服这个问题?!

【问题讨论】:

    标签: c# .net sockets io tcpclient


    【解决方案1】:

    您需要在您的消费者 DFA 和套接字客户端之间添加一个额外的缓冲区组件。

    只要有来自NetworkStream 的数据可用,缓冲区组件就会读取它并将其附加到它自己的私有缓冲区,从而增加一个“可用字节”计数器。缓冲区组件至少需要向其用户公开以下功能:

    1. BytesAvailable 属性——返回计数器的值
    2. PeekBytes(int count) 方法 -- 这将返回缓冲区的第一个 count 字节,如果至少有这么多字节可用,并且不会修改计数器或缓冲区
    3. ReadBytes(int count) 方法 -- 同上,但它将计数器递减count 并删除从缓冲区读取的字节,以便后续的PeekBytes 调用将永远不会再次读取它们

    请记住,您不需要能够为任意高的count 参数提供服务;只要您可以随时接收到最长的消息,您就可以为count 提供服务。

    显然,缓冲区组件需要保留某种数据结构,以允许某种“环绕”;您可能想研究一个循环(环形)缓冲区实现,或者您可以只使用两个大小为N 的固定缓冲区,其中N 是最长消息的长度,并在它们变满时从一个缓冲区切换到另一个缓冲区。您应该小心,如果您的缓冲区已满,您应该停止从 NetworkStream 拉取数据,并且只有在 DFA 调用 ReadBytes 以释放一些缓冲区空间后才能继续拉取数据。

    每当您的 DFA 需要读取数据时,它都会首先询问您的缓冲阶段它已经积累了多少数据,然后进行相应的处理。它看起来像这样:

    if BytesAvailable < 2
        return; // no header to read, cannot do anything
    
    // peek at the header -- do not remove it from the buffer!
    header = PeekBytes(2);
    
    // calculate the full message length based on the header
    // if this is not possible from just the header, you might want to do this
    // iteratively, or you might want to change the header so that it is possible
    length = X; 
    
    if BytesAvailable < X
        return; // no full message to read, cannot continue
    
    header = ReadBytes(2); // to remove it from the buffer
    message = ReadBytes(X); // remove the whole message as well
    

    这样,您的 DFA 将只处理整个消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多