如果读取的字节太多,命名管道将抛出



我一直在使用命名管道进行进程间通信。到目前为止,只要消息的长度不超过管道缓冲区(1024字节),就可以正常工作。

事实上,我认为任何管道都能够说出它所包含的当前数据长度。显然只能找到。这很好,但为什么NamedPipeClientStream在读取过多字节时会引发ArgumentException?

如果Stream没有Length属性(抛出NotImplementedException),我应该如何知道我可以读取多少字节?

这是我为客户端编写的代码。它应该像流上的任何其他缓冲读取操作一样:

// Create message
PipeMessage message = PipeMessage.CreateIncomingMessage((byte) firstByte);
byte[] buffer = new byte[client.InBufferSize];
int bytesRead, offset = 0;
try
{
    while ((bytesRead = client.Read(buffer, offset, buffer.Length)) > 0)
    {
        message.Append(buffer, bytesRead);
        offset += bytesRead;
    }
}
catch (Exception ex)
{
    Log("[ERROR] Reading message failed: " + ex.Message + ex.StackTrace, _clientLogger);
}

如何读取超过输入缓冲区大小的消息?还是我需要浪费资源并设置一个非常大的缓冲区,仅仅因为?

我通常有不超过50-500字节的消息。但有些更长(记录消息)。

我该如何处理?

您的管道是用PIPE_TYPE_MESSAGE打开的,而不是用PIPE_TYPE_BYTE打开的。这就是为什么如果您没有阅读完整的消息,代码就会抛出。(您的阅读模式为PIPE_READMODE_MESSAGE)。

有关更多详细信息,请参见CreateNamedPipe文档。基本上,如果对方写入大小为N的消息,则您的读取必须提供大小为N(或更大)的缓冲区。

如果您不喜欢面向消息的样式,而是更喜欢将管道视为字节流(然后必须解析),则可能需要找到相应的方法来配置管道。

您与另一端代码的合同至少应该由1个要求定义,例如最大消息长度=<任何有意义的东西>。

如果您根本找不到一个好的消息大小上限,那么另一种选择是定义一个协议。这可以很容易:

<messageLength:uint32><message data>

最新更新