Reputation: 2173
I've been using Named Pipes for Inter-Process communication. So far this works just fine, as long as the message is not longer as the pipe buffer (1024 bytes).
I actually thought that any Pipe is able to tell the current data length it contains. Obviously only seekable. This is fine, but why is NamedPipeClientStream throwing an ArgumentException when you read too many bytes?
How should I know how many bytes I can read if the Stream has no Length property (throws NotImplementedException)?
This is my code for the client-side. It should be like any other buffered-read operation on streams:
// 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);
}
How can I read messages above the size of the input buffer? Or do I need to waste resources and set an extremly large buffer, just because?
I normally have messages which are not larger than ~50-500 bytes. But some are longer (logging messages).
How can I handle this?
Upvotes: 0
Views: 1805
Reputation: 11885
Your pipe is opened with PIPE_TYPE_MESSAGE
and not with PIPE_TYPE_BYTE
.
This is why the code throws if you do not read a full message. (Your read mode is PIPE_READMODE_MESSAGE
).
See CreateNamedPipe documentation for further details. Basically, if the other side writes a message of size N, your read must provide the buffer of size N (or more).
If you do not like the message oriented style and instead prefer to treat the pipe as a byte stream (which then you must parse), you might want to find a way to configure the pipe accordingly.
Your contract with the code on the other side should at least be defined by 1 requirement, such as the maximum message length = <whatever makes sense>.
If you simply cannot find a good upper limit for your message size, then the alternative is to define a protocol. This can be as easy as:
<messageLength:uint32><message data>
Upvotes: 3