Dialecticus Dialecticus - 13 days ago 9
C# Question

Bytes are lost when writing a lot to network pipe

I want to send some bytes over a named pipe, between two computers. Client sends 65537 bytes and

PipeStream.Write()
returns as if the bytes were sent, but server never receives those bytes. Why is the client lying to me? I guess I can send my bytes in chunks, but was under the impression that
PipeStream.Write
would do that for me. One of the machines is virtual, one physical. If client sends one byte less (65536 bytes) server will receive them all. In another case, where both machines are physical, all 65537 bytes are also received just fine. Here is the code to reproduce the behavior. Run
test.exe 100000 -
on one machine and
test.exe 65537 other.comp.name
on the other machine:

class Program
{
const string PipeName = "TestPipe";

static void Main(string[] args)
{
int bufferSize = int.Parse(args[0]);

if (args[1] == "-")
{
using (var server = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 1,
PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
server.WaitForConnection();

byte[] result = new byte[bufferSize];

for (int offset = 0; offset < bufferSize; )
{
IAsyncResult asyncResult = server.BeginRead(result, offset, bufferSize - offset, null, null);

asyncResult.AsyncWaitHandle.WaitOne();

int bytesRead = server.EndRead(asyncResult);

if (bytesRead == 0)
{
Console.WriteLine("Client closed the pipe after {0} bytes.", offset);
return;
}

offset += bytesRead;
}

Console.WriteLine("All bytes are read.");
}
}
else
{
using (var client = new NamedPipeClientStream(args[1], PipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
{
client.Connect(1000);

byte[] buffer = new byte[bufferSize];

client.Write(buffer, 0, buffer.Length);

client.WaitForPipeDrain();

Console.WriteLine("All bytes are written.");
}
}
}
}

Answer

I just accepted the fact that C# lies to me when VM limit of 64KB is involved. Workaround is to send bytes in chunks, and speak of it no more.