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

时间:2015-02-20 12:20:28

标签: c# stream named-pipes

我一直在使用命名管道进行进程间通信。到目前为止,这个工作正常,只要消息不再是管道缓冲区(1024字节)。

我实际上认为任何Pipe都能告诉它包含的当前数据长度。显然只有可以寻找。这很好,但是当读取太多字节时,为什么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字节的消息。但有些更长(记录消息)。

我该如何处理?

1 个答案:

答案 0 :(得分:3)

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

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

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

您与另一方代码的合同至少应该由1个要求定义,例如最大消息长度=<无论什么意义>。

如果您根本找不到邮件大小的良好上限,则可以选择定义协议。这可以很简单:

<messageLength:uint32><message data>