2011-04-13 102 views
0

我在C#中遇到了Windows上命名管道的奇怪問題。Windows命名管道無法通過網絡工作?

客戶:

NamedPipeClientStream pipeStream = new NamedPipeClientStream("default-PC","mypipe"); 

    pipeStream.Connect(); 
    BinaryWriter sw = new BinaryWriter(pipeStream); 
    sw.Write((byte[]) data); 

服務器:

NamedPipeServerStream pipeStream = new NamedPipeServerStream("mypipe"); 
    byte[] dataAll = null; 
    pipeStream.WaitForConnection(); 
    dataAll = new BinaryReader(pipeStream).ReadBytes(1024 * 1000 * 512); 

-

如果我使用 「」作爲NamedPipeClientStream構造函數中的服務器名稱,一切正常,即服務器填充dataAll對象。

現在奇怪的是,如果我的另一隻手的NamedPipeClientStream將計算機(「默認-PC」)的網絡名稱,如顯示在上面的代碼中則沒有數據被讀取服務器上作爲服務器代碼中的ReadBytes返回一個空數組。

這可以理解我在兩臺不同的計算機上運行服務器和客戶端,但它們都在同一臺計算機上運行。唯一的區別是NamedPipeClientStream 中的「服務器名稱」參數是否爲「。」或實際的網絡名稱(甚至本地主機)。

任何想法?

回答

1

所以得出的結論是:「」

如果NamedPipeClientStream服務器名稱參數比別的東西那麼底層實現就是通過一個傳輸層,在單個寫操作中支持最大64k。問題是如果你寫超過64k,那麼數據就會消失,而不是拋出異常。

解決方案是直接使用NamedPipeClientStream並將數據寫入少於64kb的塊。

+0

@ user357320:通常情況下,這是不正確的。在我的64位Vista機器上,您的代碼適用於「。」和,數據大小至少爲50MB。在數據大小爲500MB的情況下,我的服務進程因OutOfMemoryException而崩潰,同時包含「。」和。 – 2011-05-16 12:15:32

+0

我在Win7 x64機器上運行代碼。也許實現是不同的,但無論如何,當我嘗試發送超過64k的數據時,數據從未到達 - 至少使用默認設置。 – Karlth 2011-05-17 13:50:12

2

我相信這兩個「。」和「本地主機」被認爲是特殊名稱,不使用正常的網絡連接,而是使用某種形式的環回。

當您指定一個計算機名稱,甚至您自己的計算機的名稱,它使用標準的網絡協議/堆棧/等。

您可能需要打開防火牆端口。 TCP 445.另外,默認爲,Windows允許所有傳出通信。您只需要添加入站端口例外。您的配置可能會有所不同。 .NET 3.5 (C#) Named pipes over network

+0

我關掉了防火牆,沒有任何改變。無論如何,管道連接正確,只是沒有數據似乎通過它。也不是「本地主機」或網絡名稱的工作,只有「。」 (或不指定服務器)。 – Karlth 2011-04-13 22:05:39

+0

啊,對不起,我沒有明白。那時我不知所措。我只是試圖將你的代碼粘貼到兩個項目中,我使用localhost和我的實際工作站名稱。兩人都工作。在我的客戶端中,我將數據定義爲「byte [] data = {1,2,3};」 – Jim 2011-04-13 22:54:31

+0

另外,我在64位Windows機器上使用VS 2010,.NET Framework 4 Client Profile。 – Jim 2011-04-13 22:56:14