我一直在使用命名管道进行进程间通信。到目前为止,这个工作正常,只要消息不再是管道缓冲区(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字节的消息。但有些更长(记录消息)。
我该如何处理?
答案 0 :(得分:3)
您的管道使用PIPE_TYPE_MESSAGE
而不是PIPE_TYPE_BYTE
打开。
如果您没有阅读完整的消息,这就是代码抛出的原因。 (您的阅读模式为PIPE_READMODE_MESSAGE
)。
有关详细信息,请参阅CreateNamedPipe文档。 基本上,如果另一方写入大小为N的消息,则您的读取必须提供大小为N(或更多)的缓冲区。
如果您不喜欢面向消息的样式,而是喜欢将管道视为字节流(然后您必须解析),您可能希望找到一种相应配置管道的方法。
您与另一方代码的合同至少应该由1个要求定义,例如最大消息长度=<无论什么意义>。
如果您根本找不到邮件大小的良好上限,则可以选择定义协议。这可以很简单:
<messageLength:uint32><message data>