在向网络管道写入很多时,字节丢失了

时间:2016-11-04 18:04:58

标签: c# windows named-pipes

我想在两台计算机之间的命名管道上发送一些字节。客户端发送65537个字节,PipeStream.Write()返回,就好像发送了字节一样,但服务器从不接收这些字节。为什么客户骗我?我想我可以用块发送我的字节,但是我觉得PipeStream.Write会为我做这个。其中一台机器是虚拟的,一台是物理机器。如果客户端发送少一个字节(65536字节),服务器将全部接收它们。在另一种情况下,两台机器都是物理机器,所有65537字节也都收到了。这是重现行为的代码。在一台计算机上运行test.exe 100000 -,在另一台计算机上运行test.exe 65537 other.comp.name

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.");
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您在PipeTransmissionMode.Byte中使用管道。期望在此模式下发送数据和完成加工处理。在这种情况下,在您的服务器代码中,您不应该停止读取0字节。而是检查server.IsConnected,一旦客户端关闭管道,这意味着所有数据都会被发送,此值将变为false。你可能会得到一些bytesRead == 0读数。

答案 1 :(得分:0)

我刚接受了当涉及到64 KB的VM限制时C#对我而言的事实。解决方法是以块的形式发送字节,不再说它。