2012-08-14 143 views
1

我有一個WCF命名管道服務器,一個非WCF命名管道服務器,一個WCF命名管道客戶端和一個非wcf命名管道客戶端。WCF客戶端無法連接到非WCF命名管道服務器

非wcf客戶端可以連接到兩臺服務器。 wcf客戶端只能連接到wcf服務器。當我嘗試將它連接到非wcf客戶端時,我得到這個異常。

Unhandled Exception: System.ServiceModel.EndpointNotFoundException: There was no endpoint 
listening at net.pipe://localhost/PipePlusFive that could accept the message. This is 
often caused by an incorrect address or SOAP action. See InnerException, 
if present, for more details. ---> System.IO.PipeException: The pipe endpoint 
'net.pipe://localhost/PipePlusFive' could not be found on your local machine. 

---內部異常堆棧跟蹤的結尾---

根據this管的實際名稱是存儲在存儲器映射文件中的GUID。我認爲這是爲wcf客戶端和服務器自動處理的。對於非wcf服務器,我創建了內存映射文件,向它寫入一個GUID,然後使用該GUID作爲名稱創建管道。在非wcf客戶端中,我打開內存映射文件,從中讀取管道名稱,然後使用該名稱連接到管道。然後,事實上,我可以使用非wcf客戶端連接到兩臺服務器而無需更改任何內容,這讓我相信我正在服務器和客戶端上正確實施此部分。

另外,當我啓動非wcf服務器時,啓動wcf服務器,第二次崩潰,聲明它不能監聽該管道名稱,因爲另一個端點已在監聽。

我想知道爲什麼wcf客戶端無法找到非wcf服務器時,非wcf客戶端可以找到兩者?除了我鏈接到的博客中描述的內容之外,還有什麼其他wcf用來查找終點?

UPDATE:

這裏是我使用WCF客戶端代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     ChannelFactory<IPlusFive> pipeFactory = 
      new ChannelFactory<IPlusFive>(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress("net.pipe://localhost/PipePlusFive")); 

     IPlusFive pipeProxy = pipeFactory.CreateChannel(); 

     while (true) 
     { 
      string str = Console.ReadLine(); 
      if (str.Equals("q")) 
      { return; } 
      Console.WriteLine(pipeProxy.PlusFive(Int32.Parse(str))); 
     } 
    } 
} 

這裏是我使用的WCF服務器的代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var inst = new PlusFiver(); 
     using (ServiceHost host = new ServiceHost(inst, 
      new Uri[] { new Uri("net.pipe://localhost") })) 
     { 
      host.AddServiceEndpoint(typeof(IPlusFive), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "PipePlusFive"); 
      host.Open(); 
      Console.WriteLine("Service is Available. Press enter to exit."); 
      Console.ReadLine(); 
      host.Close(); 
     } 
    } 
} 

以下是我用於非WCF服務器的代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine("Creating Memory Mapped file..."); 
     string fileName = GenerateFileMapName(String.Empty); 
     Guid pipeName = Guid.NewGuid(); 
     Console.WriteLine(" writing pipe name: " + pipeName.ToString("D")); 
     MemoryMappedFile mmf = null; 
     var messageList = new List<byte>(); 
     try 
     { 
      mmf = WritePipeName(fileName, pipeName); 
      Console.WriteLine("Creating Named Pipe"); 
      Console.WriteLine("Pipe Name: " + GetPipeNameFromMappedFile(fileName, mmf)); 
      using (var pipe = new NamedPipeServerStream(pipeName.ToString("D"), PipeDirection.InOut)) 
      { 
       Console.WriteLine("pipe created"); 
       Console.WriteLine("Waiting for connection"); 
       pipe.WaitForConnection(); 
       Console.WriteLine("Received Connection"); 
       Console.WriteLine("Waiting to receive data"); 
       var bytes = new byte[7]; 
       pipe.Read(bytes, 0, 7); 
       messageList.AddRange(bytes); 
       bytes = new byte[messageList[6]]; 
       pipe.Read(bytes, 0, messageList[6]); 
       messageList.AddRange(bytes); 
       bytes = new byte[2]; 
       pipe.Read(bytes, 0, 2); 
       messageList.AddRange(bytes); 
       messageList.Add((byte)pipe.ReadByte()); 
       pipe.WriteByte(0x0b); 
       WriteList(messageList); 
       Console.WriteLine("Finished reading from pipe"); 
       PrintBytes(bytes); 
       Console.WriteLine("Closing Connection"); 
       pipe.Disconnect(); 
       Console.WriteLine("Pipe disconnected"); 
       //Console.Read(); 
      } 
     } 
     finally 
     { 
      mmf.Dispose(); 
     } 

    } 

    private static void WriteList(List<byte> messageList) 
    { 
     foreach (var b in messageList) 
     { 
      Console.Write(b.ToString("x2") + " "); 
     } 
     Console.WriteLine(); 
    } 

    private static void PrintBytes(byte[] bytes) 
    { 
     foreach (var b in bytes) 
     { 
      Console.Write(b.ToString("x2") + " "); 
     } 
     Console.WriteLine(); 
    } 

    private static string GenerateFileMapName(string uri) 
    { 
     return "net.pipe:EbmV0LnBpcGU6Ly8rLw=="; 
    } 

    private static MemoryMappedFile WritePipeName(string fileName, Guid pipeName) 
    { 
     var mmf = MemoryMappedFile.CreateNew(fileName, pipeName.ToByteArray().Count()); 

      Console.WriteLine("Memory Mapped File Created."); 
      using (var accessor = mmf.CreateViewAccessor(4, 45)) 
      { 
       Console.WriteLine("Writing pipe name to file"); 
       accessor.Write(0, ref pipeName); 
       Console.WriteLine("Finished writing pipe name to file"); 
      } 
     return mmf; 
    } 

    private static string GetPipeNameFromMappedFile(string filename, MemoryMappedFile mmf) 
    { 
     Guid pipeName; 
     using (var accessor = mmf.CreateViewAccessor(4, 45)) 
     { 

      accessor.Read<Guid>(0, out pipeName); 
     } 
     return pipeName.ToString("D"); 
    } 
} 

回答

0

WCF端點netNamedPipeBinding旨在連接到WCF命名管道服務器。當WCF客戶端使用這種類型的綁定建立連接時,它將執行與您提到的the article中指定的相同的準備工作。 post將澄清其餘的細節。

+0

我已經添加了我的代碼。你能看到我在做錯什麼嗎? – scott 2012-08-15 12:41:54