2

我们有一个 C# 应用程序,它使用一个相对简单的协议通过 TCP/IP 与设备通信,该协议由一系列消息组成,这些消息具有固定大小的标头和可变长度的有效负载。标头包含有效负载的长度。

最近我们将编程模型从同步转换为异步,现在有一个有趣的问题:如何处理部分接收到的消息。

同步码

public void ReceiveMessage(NetworkStream stream)
{
    // Read the header from the stream
    MessageHeader header = stream.ReadHeader();

    int payloadBytesRead = 0;
    byte[] buffer = new byte[header.PayloadSize];

    // Keep reading from the stream until the payload
    // is fully extracted
    while (payloadBytesRead < header.PayloadSize)
    {
        payloadBytesRead += stream.Read(buffer, payloadBytesRead, header.PayloadSize - payloadBytesRead);
    }

    MessagePayload = new MessagePayload(buffer);

    // Do something with the message here
    // ...

}

where是从流中提取固定大小标头ReadHeader的扩展方法。NetworkStream

异步版本的问题

在我们使用BeginReadand的异步版本中,EndRead读取回调可能会被缓冲区中的部分接收消息调用。由于回调是在从流中提取数据后调用的,因此不可能将部分消息留在流中以供下一个回调使用。但是,我们必须将这部分数据保留到下一次回调,以便以后处理。

似乎唯一的解决方案是将部分数据字节复制到不同的缓冲区,或者在BeginRead调用下一个缓冲区之前将它们移动到接收缓冲区的底部。这是正确的,还是有更常见的技术来处理这种情况?

4

0 回答 0