我正在使用命名管道在我正在進行的項目中,雙方都用C#(客戶機和服務器)編寫,並且兩者都在同一臺計算機上(命名管道用於RPC)。兩側的命名管道設置爲使用'PipeTransmissionMode.Message'模式,根據我的理解,應該將每個數據塊「打包」到一個單獨的消息中的pipe.Write()和另一端的pipe.Read()應該收到全部信息或者不收到全部信息。C#在消息模式下命名管道有時會合並消息?
在試圖反序列化接收端的數據時,我看到我獲得了大量的數據,比我發送的數據包大。於是我做了一個小測試,我創建了兩個應用程序,服務器和客戶端,它看起來像這樣:
服務器:
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,其次是「大」。這是怎麼回事?
PS:如果我把Thread.Sleep(100)
在服務器上環,它工作正常(只有32個寫在兩面)
編輯: 如果我把在客戶端服務器上的Thread.Sleep(100)
和Thread.Sleep(200)
,我收到更大的數據包更頻繁,這導致我相信,如果在讀取調用之前有多條消息到達,那麼讀取將返回所有這些消息。我怎樣才能確保每次閱讀只會返回一條消息?
您不應該將'ReadMode'設置爲'Message'嗎?此外,您還需要在客戶端流上設置 - 默認情況下,它處於「字節」模式。 – Luaan
@Luaan'NamedPipeClientStream'的構造函數沒有接受'PipeTransmissionMode'的重載,我還沒有找到創建後設置它的方法。 – UnTraDe
'ReadMode'有一個setter - 它應該在創建(或連接)管道後設置。 – Luaan