2016-02-20 112 views
2

我有兩個用C++和c#編寫的程序。我想在它們之間建立一個使用命名管道的雙向通信。 C#客戶端程序可以連接到由C++服務器程序創建的命名管道,但兩端都沒有收到。c#命名管道雙向通信

這裏是C++部分(服務器):

#include <iostream> 
#include <windows.h> 
#include <stdlib.h> 
#define UNICODE 
using namespace std; 
HANDLE hnamedPipe = INVALID_HANDLE_VALUE; 
BOOL Finished =false; 
HANDLE hThread = NULL; 
unsigned long __stdcall CS_RcvThr(void * pParam) ; 
int main(int argc, char **argv) 
{ 
    hnamedPipe = CreateNamedPipe(
     "\\\\.\\pipe\\vikeyP", 
     PIPE_ACCESS_DUPLEX, 
     PIPE_TYPE_MESSAGE| 
     PIPE_READMODE_MESSAGE| 
     PIPE_WAIT, 
     PIPE_UNLIMITED_INSTANCES, 
     1024, 
     1024, 
     NMPWAIT_USE_DEFAULT_WAIT, 
     NULL); 

    if(hnamedPipe == INVALID_HANDLE_VALUE) 
    { 
     cout << "Failed" << endl; 
    } 

    while (true) 
    { 
     cout<< "Waiting for client"<< endl; 
     if(!ConnectNamedPipe(hnamedPipe,NULL)) 
     { 
      if(ERROR_PIPE_CONNECTED != GetLastError()) 
      { 
       cout << "FAIL"<< endl; 
      } 
     } 
     else 
     { 
      cout<<"Connected!"<<endl; 
      hThread = CreateThread(NULL, 0, &CS_RcvThr, NULL, 0, NULL); 
      if(hThread) cout<<"read thread created"<<endl; else cout<<"cant crat rd thed\n"; 
      break; 
     } 
    } 

    while(1) 
    { 
     cout<<"lst loop"<<endl; 
     //Send over the message 
     char chResponse[] = "hello\n"; 
     DWORD cbResponse,cbWritten; 
     cbResponse = sizeof(chResponse); 

     if (!WriteFile(
     hnamedPipe, 
     chResponse, 
     cbResponse, 
     &cbWritten, 
     NULL)) 
     { 
      wprintf(L"failiure w/err 0x%08lx\n",GetLastError); 
     } 
     cout<<"Sent bytes :)" << endl; 
     Sleep(10); 
    } 
} 

unsigned long __stdcall CS_RcvThr(void * pParam) { 
    BOOL fSuccess; 
    char chBuf[100]; 
    DWORD dwBytesToWrite = (DWORD)strlen(chBuf); 
    DWORD cbRead; 
    int i; 

    while (1) 
    { 
     fSuccess =ReadFile(hnamedPipe,chBuf,dwBytesToWrite,&cbRead, NULL); 
     if (fSuccess) 
     { 
      printf("C++ App: Received %d Bytes : ",cbRead); 
      for(i=0;i<cbRead;i++) 
       printf("%c",chBuf[i]); 
      printf("\n"); 
     } 
     if (! fSuccess && GetLastError() != ERROR_MORE_DATA) 
     { 
      printf("Can't Read\n"); 
      if(Finished) 
       break; 
     } 
    } 
} 

這裏是C#部分(客戶端):

private Thread vikeyClientThread; 
    public void ThreadStartClient() 
    { 
     Console.WriteLine("Thread client started ID ={0} name = {1} " , 
     Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.Name); 
     using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "vikeyP")) 
     { 
      // The connect function will indefinately wait for the pipe to become available 
      // If that is not acceptable specify a maximum waiting time (in ms) 
      Console.WriteLine("Connecting to ViKEY server..."); 
      pipeStream.Connect(); 
      Console.WriteLine("Connected :)"); 

      //Write from client to server 
      StreamWriter sw = new StreamWriter(pipeStream); 
      while (true) 
      { 
       //Read server reply 
       StreamReader sr = new StreamReader(pipeStream); 
       string temp = ""; 
       sw.WriteLine(System.DateTime.Now); 
       byte[] c = new byte[200]; 
       temp = sr.ReadLine(); 
       pipeStream.Read(c, 0, c.Length); 
       Console.WriteLine("RX =:{0}", Encoding.UTF8.GetString(c, 0, c.Length)); 
       Thread.Sleep(500); 
      } 
     } 
     Console.WriteLine("Vikey pipe Closed"); 
     Console.WriteLine("Thread with ID ={0} name = {1} is closed.", 
     Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.Name); 
    } 
+0

儘管發生了什麼?錯誤在哪裏?你期望會發生什麼以及會發生什麼?什麼控制檯輸出正在發生? – misha130

+0

@ misha130在C#控制檯中,它應該打印「hello」,並在C++控制檯中它應該發送當前的日期和時間。 – arunmj

+1

你嘗試'C++到C++'或'C#到C#'嗎?也許,使用不同的語言不是問題... –

回答

0

你設置了服務器端起來的消息類型VS字節類型。如果您想讀取任意數量的字節,則需要使用名爲pipe的字節類型。

您正在將流包裝在2個對象中,一個StreamReader和一個StreamWriter。不要這樣做,只需使用Stream。你正在嘗試逐行閱讀,不要那樣做。而是發送要讀取的字節數,然後再發送字節。在客戶端你會讀取字節數,然後創建一個足夠大的緩衝區然後讀取。如果是文本數據,則可以使用編碼器(可能是ASCII)將其轉換回C#字符串。

你的while(true)應該檢測服務器何時關閉管道。

您應該考慮使用異步命名管道。