消息模式下的 C# Named Pipes 有时会合并消息?
C# Named Pipes in message mode sometimes merge messages?
我在我正在处理的项目中使用命名管道,双方都是用 C# 编写的(客户端和服务器)并且都在同一台计算机上(命名管道用于 RPC)。两侧的命名管道都设置为使用 'PipeTransmissionMode.Message' 模式,根据我的理解,每个数据块应该 "pack" 在一条消息中传递给 pipe.Write() 并且 pipe.Read () 另一端应该收到整个消息或 none。
在接收端尝试反序列化数据时,我发现我收到了大量数据,比我发送的数据包还大。所以我做了一个小测试,我创建了两个应用程序,服务器和客户端,它看起来像这样:
服务器:
class Program
{
static void Main(string[] args)
{
NamedPipeServerStream pipe = new NamedPipeServerStream("TestPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024);
pipe.WaitForConnection();
Random random = new Random();
while(true)
{
byte[] buffer = new byte[32];
random.NextBytes(buffer);
pipe.Write(buffer, 0, buffer.Length);
Console.WriteLine(buffer.Length);
}
}
}
客户:
class Program
{
static void Main(string[] args)
{
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut, PipeOptions.Asynchronous);
pipe.Connect();
while(true)
{
byte[] buffer = new byte[2048];
int read = pipe.Read(buffer, 0, buffer.Length);
Console.WriteLine(read);
if(read > 32)
Console.WriteLine("Big");
}
}
}
运行 这样,服务器只输出 32(这是我所期望的)但是客户端,有时输出 64 后跟 "Big"。怎么回事?
P.S:如果我将 Thread.Sleep(100)
放在服务器循环上,它会按预期工作(两边只写 32)
编辑:
如果我在服务器上放置 Thread.Sleep(100)
并在客户端上放置 Thread.Sleep(200)
,我会更频繁地收到更大的数据包,这使我相信如果在调用 read 之前到达了多个消息,则读取 return都是他们。我如何确保每次阅读 return 只有一条消息?
您也忘记将 ReadMode
设置为 Message
:
pipe.ReadMode = PipeTransmissionMode.Message;
创建或连接到管道时,无论 TransmissionMode
设置如何,默认模式始终为 Byte
。
我在我正在处理的项目中使用命名管道,双方都是用 C# 编写的(客户端和服务器)并且都在同一台计算机上(命名管道用于 RPC)。两侧的命名管道都设置为使用 'PipeTransmissionMode.Message' 模式,根据我的理解,每个数据块应该 "pack" 在一条消息中传递给 pipe.Write() 并且 pipe.Read () 另一端应该收到整个消息或 none。
在接收端尝试反序列化数据时,我发现我收到了大量数据,比我发送的数据包还大。所以我做了一个小测试,我创建了两个应用程序,服务器和客户端,它看起来像这样:
服务器:
class Program
{
static void Main(string[] args)
{
NamedPipeServerStream pipe = new NamedPipeServerStream("TestPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 1024, 1024);
pipe.WaitForConnection();
Random random = new Random();
while(true)
{
byte[] buffer = new byte[32];
random.NextBytes(buffer);
pipe.Write(buffer, 0, buffer.Length);
Console.WriteLine(buffer.Length);
}
}
}
客户:
class Program
{
static void Main(string[] args)
{
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut, PipeOptions.Asynchronous);
pipe.Connect();
while(true)
{
byte[] buffer = new byte[2048];
int read = pipe.Read(buffer, 0, buffer.Length);
Console.WriteLine(read);
if(read > 32)
Console.WriteLine("Big");
}
}
}
运行 这样,服务器只输出 32(这是我所期望的)但是客户端,有时输出 64 后跟 "Big"。怎么回事?
P.S:如果我将 Thread.Sleep(100)
放在服务器循环上,它会按预期工作(两边只写 32)
编辑:
如果我在服务器上放置 Thread.Sleep(100)
并在客户端上放置 Thread.Sleep(200)
,我会更频繁地收到更大的数据包,这使我相信如果在调用 read 之前到达了多个消息,则读取 return都是他们。我如何确保每次阅读 return 只有一条消息?
您也忘记将 ReadMode
设置为 Message
:
pipe.ReadMode = PipeTransmissionMode.Message;
创建或连接到管道时,无论 TransmissionMode
设置如何,默认模式始终为 Byte
。