2010-06-08 2 views
7

명명 된 파이프 101 문제가있는 것 같습니다. C++ 관리되지 않는 응용 프로그램에서 C# 관리되는 응용 프로그램으로 전송되는 단방향 명명 된 파이프를 연결하는 간단한 설정이 있습니다. 파이프가 연결되지만 버퍼를 플러시하고 메시지를 전달하는 것처럼 보이는 핸들을 닫지 않으면 파이프를 통해 "메시지"를 보낼 수 없습니다. 마치 메시지가 차단 된 것과 같습니다. 클라이언트/서버의 역할을 바꾸어보고 행운을 불어 넣지 않고 다른 플래그 조합으로 호출하려고했습니다. C#에서 관리되지 않는 C++로 메시지를 다른 방향으로 쉽게 보낼 수 있습니다. 누구나 통찰력을 가지고 있습니까? 어떤 사람들이 관리되지 않는 C++에서 성공적으로 C#으로 메시지를 보낼 수 있습니까? 내부적 인 amanged 또는 unmanaged 파이프의 예제를 많이 찾을 수 있지만 unamanged에서 inter/managed로 관리 할 수는 없습니다. 단지 수행 할 수 있다고 주장합니다.네임드 파이프 문자열을 관리 대상 코드 공간으로 보내는 방법은 무엇입니까?

목록에서 명확성을 위해 많은 래퍼 항목을 생략했습니다. 관련성이 있다고 생각되는 핵심 비트는 파이프 연결/생성/읽기 및 쓰기 메소드입니다. 블로킹/스레딩에 대해 너무 걱정하지 마십시오.

C#을 서버 측

// This runs in its own thread and so it is OK to block 
    private void ConnectToClient() 
    { 
     // This server will listen to the sending client 
     if (m_InPipeStream == null) 
     { 
      m_InPipeStream = 
       new NamedPipeServerStream("TestPipe", PipeDirection.In, 1); 
     } 

     // Wait for client to connect to our server 
     m_InPipeStream.WaitForConnection(); 

     // Verify client is running 
     if (!m_InPipeStream.IsConnected) 
     { 
      return; 
     } 

     // Start listening for messages on the client stream 
     if (m_InPipeStream != null && m_InPipeStream.CanRead) 
     { 
      ReadThread = new Thread(new ParameterizedThreadStart(Read)); 
      ReadThread.Start(m_InPipeStream); 
     } 
    } 


    // This runs in its own thread and so it is OK to block 
    private void Read(object serverObj) 
    { 
     NamedPipeServerStream pipeStream = (NamedPipeServerStream)serverObj; 
     using (StreamReader sr = new StreamReader(pipeStream)) 
     { 
      while (true) 
      { 
       string buffer = "" ; 
       try 
       { 
        // Blocks here until the handle is closed by the client-side!! 
        buffer = sr.ReadLine(); // <<<<<<<<<<<<<< Sticks here 
       } 
       catch 
       { 
        // Read error 
        break; 
       } 

       // Client has disconnected? 
       if (buffer == null || buffer.Length == 0) 
        break; 

       // Fire message received event if message is non-empty 
       if (MessageReceived != null && buffer != "") 
       { 
        MessageReceived(buffer); 
       } 
      } 
     } 
    } 

C++ 클라이언트 측

// Static - running in its own thread. 
    DWORD CNamedPipe::ListenForServer(LPVOID arg) 
    { 
     // The calling app (this) is passed as the parameter 
     CNamedPipe* app = (CNamedPipe*)arg; 

     // Out-Pipe: connect as a client to a waiting server 
     app->m_hOutPipeHandle = 
     CreateFile("\\\\.\\pipe\\TestPipe", 
       GENERIC_WRITE, 
       0, 
       NULL, 
       OPEN_EXISTING, 
       FILE_ATTRIBUTE_NORMAL, 
       NULL); 
     // Could not create handle 
     if (app->m_hInPipeHandle == NULL || 
      app->m_hInPipeHandle == INVALID_HANDLE_VALUE) 
     { 
      return 1; 
     } 

     return 0; 
    } 


    // Sends a message to the server 
    BOOL CNamedPipe::SendMessage(CString message) 
    { 
    DWORD dwSent; 

     if (m_hOutPipeHandle == NULL || 
      m_hOutPipeHandle == INVALID_HANDLE_VALUE) 
     { 
      return FALSE; 
     } 
     else 
     { 
      BOOL bOK = 
       WriteFile(m_hOutPipeHandle, 
          message, message.GetLength()+1, &dwSent, NULL); 
      //FlushFileBuffers(m_hOutPipeHandle);    // <<<<<<< Tried this 
      return (!bOK || (message.GetLength()+1) != dwSent) ? FALSE : TRUE; 
     } 
    } 


    // Somewhere in the Windows C++/MFC code... 
    ... 
    // This write is non-blocking. It just passes through having loaded the pipe. 
    m_pNamedPipe->SendMessage("Hi de hi"); 
    ... 

답변

8

sr.ReadLine()는 개행 문자 (들) 라인의 끝을 알아 볼 것으로 기대하고있다. new-line이나 end-of-stream을받지 못하기 때문에 더 기다립니다. 시도 :

m_pNamedPipe->SendMessage("Hi de hi\n") 

또는 sr.Read() 메소드의 일부.

+0

그게 전부 야! 이제는 모두 작동합니다. 많은 감사드립니다. 나는 개행의 필요성을 완전히 잊었다. 나는 메시지 포맷 (레이어 -2)에 대해 잊어 버린 파이프 (레이어 -1)의 메커니즘에 너무 집중했다. – user320240

관련 문제