2015-08-30 119 views
1

我有一個名稱管道服務器。客戶端發送消息,看起來沒問題,但服務器掛在線路上var stringData = textReader.ReadToEnd();命名管道掛在讀

var namedPipeServerStream = new NamedPipeServerStream(_pipeName, 
         PipeDirection.In, 
         1, 
         PipeTransmissionMode.Byte, 
         PipeOptions.Asynchronous); 

namedPipeServerStream.WaitForConnection(); 

using (var textReader = new StreamReader(namedPipeServerStream)) 
{ 
    var stringData = textReader.ReadToEnd(); 

    _callback(stringData); 

    namedPipeServerStream.Flush(); 
    namedPipeServerStream.Close(); 
} 

Thread.Sleep(1); 

客戶端看起來就像這樣:

public void Send(string message) 
{ 
    var pipeStream = new NamedPipeClientStream(_serverName, 
     _pipeName, 
     PipeDirection.Out, 
     PipeOptions.Asynchronous); 

    pipeStream.Connect(_timeout); 

    var buffer = UTF8.GetBytes(message); 

    pipeStream.Write(buffer, 0, buffer.Length); 
} 

這是爲什麼掛?

回答

3

命名管道流(如網絡流)沒有明確的結束,它們只是暫時「乾涸」,這就是爲什麼您的ReadToEnd調用會無限期地嘗試讀取更多數據。

但是,你可以在PipeTransmissionMode更改爲Message在服務器端,使每個寫入被視爲一個單獨的消息管道,然後從流中讀取直到IsMessageComplete回報true。例如:

using (var namedPipeServerStream = new NamedPipeServerStream(_pipeName, 
       PipeDirection.InOut, 
       1, 
       PipeTransmissionMode.Message, 
       PipeOptions.Asynchronous)) 
{ 
    namedPipeServerStream.WaitForConnection(); 

    MemoryStream ms = new MemoryStream(); 
    byte[] buffer = new byte[0x1000]; 
    do { ms.Write(buffer, 0, namedPipeServerStream.Read(buffer, 0, buffer.Length)); } 
    while (!namedPipeServerStream.IsMessageComplete); 

    string stringData = Encoding.UTF8.GetString(ms.ToArray()); 
    _callback(stringData); 
} 

Thread.Sleep(1); 
+0

我對將'PipeTransmissionMode'設置爲'Message'的具體操作有點困惑。它是否在消息之間添加了一些界限? – BanksySan

+0

我還發現處理'NamedPipeClientStream'可以防止掛起服務器。 – BanksySan

+0

@BanksySan,沒有分隔符,一旦所有與單次寫入相關的字節都被服務器流讀取,本地操作系統API將爲「IsMessageComplete」設置底層標誌。 –