2012-05-24 6 views
4

VC++ 6 응용 프로그램과 C# 응용 프로그램 간의 양방향 통신을 시도하고 있습니다. 명명 된 파이프를 사용하고 있습니다. 내 C++ 코드에서 C# 클라이언트의 메시지를 읽을 수 있지만 서버가 "죽습니다."다시 메시지를 다시 시작해야합니다.명명 된 파이프를 사용하는 양방향 C++에서 C#으로 통신

내가 원하는 것은 C# 응용 프로그램을 C++ 응용 프로그램에 연결하고 상태를 요청하고 C++ 응용 프로그램이 꺼지고 상태를 확인한 다음 "사용 중"또는 "유휴 중 하나"를 반환합니다.

연결이 닫혔다 고해서 C# 클라이언트에 아무 것도 쓸 수 없습니다. 내가 주석 처리 한 것들은 이미 시도한 것들이다. (스레드로 시작)

C++ 코드

UINT CNamedPipe::StartNamedPipeServer() 
{ 
LPTSTR lpszPipename = "\\\\.\\pipe\\SAPipe"; 
    HANDLE hPipe; 
    BOOL flg; 
    DWORD dwWrite,dwRead; 
    char szServerUpdate[200]; 
    char szClientUpdate[200]; 

    hPipe = CreateNamedPipe ( lpszPipename, 
           PIPE_ACCESS_DUPLEX, 
           PIPE_TYPE_MESSAGE | 
           PIPE_READMODE_MESSAGE | 
           PIPE_NOWAIT,     //changed from nowait 
           PIPE_UNLIMITED_INSTANCES, // max. instances 
           BUFSIZE,     // output buffer size 
           BUFSIZE,     // input buffer size 
           PIPE_TIMEOUT,    // client time-out 
           NULL);      // no security attribute 

    if (hPipe == INVALID_HANDLE_VALUE) 
     return 0; 

    ConnectNamedPipe(hPipe, NULL); 

    while(m_bServerActive) //This seems to work well .... 
    { 

     //Read from client 
     flg = ReadFile(hPipe,szClientUpdate,strlen(szClientUpdate),&dwRead, NULL); 

     if(flg) //Read something from the client!!!! 
     { 
      CString csMsg,csTmp; 

      for(int i=0;i<dwRead;i++){ 
       csTmp.Format("%c",szClientUpdate[i]); 
       csMsg += csTmp; 
      } 


      AfxMessageBox("Client message: " + csMsg); 

      strcpy(szServerUpdate,"busy"); 

      //Write status to Client 
      flg = WriteFile(hPipe, szServerUpdate, strlen(szServerUpdate), &dwWrite, NULL); 

      EndServer(); 
      StartServer(); 
     } 

    } 

    return 0; 

}

C# 코드 : StreamWriter 또는 StreamReader 폐기

public void ThreadStartClient(object obj) 
    { 
     // Ensure that we only start the client after the server has created the pipe 
     ManualResetEvent SyncClientServer = (ManualResetEvent)obj; 

     // Only continue after the server was created -- otherwise we just fail badly 
     // SyncClientServer.WaitOne(); 

     using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "SAPipe")) 
     { 
      // The connect function will indefinately wait for the pipe to become available 
      // If that is not acceptable specify a maximum waiting time (in ms) 
      pipeStream.Connect(); 

      //Write from client to server 
      using (StreamWriter sw = new StreamWriter(pipeStream)) 
      { 
       sw.WriteLine("What's your status?"); 
      } 

      //Read server reply 
      /*using (StreamReader sr = new StreamReader(pipeStream)) 
      { 
       string temp = ""; 
       temp = sr.ReadLine(); //Pipe is already closed here ... why? 

       MessageBox.Show(temp); 

      }*/ 

      //pipeStream.Close(); 

     } 
    } 
} 

답변

8

는 기본이되는 스트림을 닫습니다.

따라서 사용 문은 스트림을 닫을 것입니다.

public void ThreadStartClient(object obj) 
    { 
      // Ensure that we only start the client after the server has created the pipe 
      ManualResetEvent SyncClientServer = (ManualResetEvent)obj; 

      // Only continue after the server was created -- otherwise we just fail badly 
      // SyncClientServer.WaitOne(); 

      using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "SAPipe")) 
      { 
       // The connect function will indefinately wait for the pipe to become available 
       // If that is not acceptable specify a maximum waiting time (in ms) 
       pipeStream.Connect(); 


       //Write from client to server 
       StreamWriter sw = new StreamWriter(pipeStream)) 
       sw.WriteLine("What's your status?"); 

       //Read server reply 
       StreamReader sr = new StreamReader(pipeStream) 
       string temp = ""; 
       temp = sr.ReadLine(); //Pipe is already closed here ... why? 

       MessageBox.Show(temp); 
      } 
    } 

또한 당신이 사용 성명에서 스트림을 감싸 때문에이 주석 pipeStream.Close() 기능이 필요하지 않은 것을 주목해야한다.

+0

감사합니다. 큰 도움이됩니다. 코드를 변경하고 무슨 일이 일어나는 지 보겠습니다. 짐작 하셨겠지만 저는 C#을 처음 사용합니다. –

+0

아무런 문제가 없습니다. 투표에서 수표를 누르는 것을 잊지 마십시오. 그러면 더 나은지지 등급을 얻게됩니다! – Blam

3

좋아, 내 응용 프로그램에서 작동하고있어 .... 감사 Blam!

다음은 C++ 서버 (스레드 내에서 이것을 실행)이다 :

UINT CNamedPipe::StartNamedPipeServer() 
{ 
    if(!m_bServerActive) 
     return 0; 

    LPTSTR lpszPipename = "\\\\.\\pipe\\MyPipe"; 
     HANDLE hPipe; 
     BOOL flg; 
     DWORD dwWrite,dwRead; 
     char szServerUpdate[200]; 
     char szClientUpdate[200]; 

     hPipe = CreateNamedPipe ( lpszPipename, 
            PIPE_ACCESS_DUPLEX, 
            PIPE_TYPE_MESSAGE | 
            PIPE_READMODE_MESSAGE | 
            PIPE_WAIT,     //HAS TO BE THIS 
            PIPE_UNLIMITED_INSTANCES, // max. instances 
            BUFSIZE,     // output buffer size 
            BUFSIZE,     // input buffer size 
            PIPE_TIMEOUT,    // client time-out 
            NULL);      // no security attribute 

     if (hPipe == INVALID_HANDLE_VALUE) 
      return 0; 

     ConnectNamedPipe(hPipe, NULL); 


     strcpy(szServerUpdate,"busy"); 

     //Write status to Client 
     flg = WriteFile(hPipe, szServerUpdate, strlen(szServerUpdate), &dwWrite, NULL); 

     EndServer(); 
     StartServer(); 

     return 0; 
} 

을 그리고 여기에 C#을 클라이언트의 : 나는 실제로 서버 때문에 클라이언트에서 아무것도를 전송하고 있지 않다

public void ThreadStartClient(object obj) 
     { 
      // Ensure that we only start the client after the server has created the pipe 
      ManualResetEvent SyncClientServer = (ManualResetEvent)obj; 

      using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut)) 
      { 

       // The connect function will indefinately wait for the pipe to become available 
       // If that is not acceptable specify a maximum waiting time (in ms) 
       pipeStream.Connect(); 

       if (!pipeStream.IsConnected) //It thinks it's connected but can't read anything .... 
       { 
        MessageBox.Show("Failed to connect ...."); 
        return; 
       } 

       //Read server reply 
       StreamReader sr = new StreamReader(pipeStream); 

       char[] c = new char[200]; 

       while (sr.Peek() >= 0) 
       { 
        sr.Read(c, 0, c.Length); 
       } 

       string s = new string(c); 
       MessageBox.Show(s); 
      } 
     } 

필자는 이렇게 할 필요가 없다. CreateNamedPipe() 함수의 PIPE_WAIT 매개 변수가 핵심이다. 이렇게하면 서버가 클라이언트 연결을 기다립니다.

관련 문제