管道通信C++

Ric*_*ras 2 c++ windows pipe

我正在编写两个必须通信的litle c ++应用程序.第一个将是一项服务,每隔一段时间,必须提醒用户一些事情.由于服务无法创建窗口,我将应用程序设计为两个独立的可执行文件.

该服务将使用通知程序进行通信.

该服务仅需要向通知器发送文本消息,该通知器将在系统托盘上显示气球.

我试图使用命名管道,我想我几乎在那里,但不是那里.到目前为止我所拥有的是:

在通知者方面:

  m_hInPipe = CreateNamedPipe(L"\\\\.\\pipe\\nhsupspipe", PIPE_ACCESS_INBOUND,
                PIPE_WAIT, 1, 1024, 1024, 60, NULL);
Run Code Online (Sandbox Code Playgroud)

意思是我创建了一个名为nhsupspipe的管道,一个入站管道.

在服务方面:

if (!WriteFile(m_hOutPipe, "My message to the user?", 23, &escritos, &o))
     std::cout << "ERROR: " << GetLastError();
Run Code Online (Sandbox Code Playgroud)

调试我可以看到一切正常,管道已创建,WriteFile将我的23个字节写入管道.

我的问题是:如何在通知器方面能够读取这些字节?是否有任何消息发送到该流程?我是否必须为管道编写处理程序?什么?

Eug*_*nca 5

来自客户端(您的服务)和服务器(通知程序)的一些简单片段[ 注意:这是根据我之前做过的项目改编而来的,这反过来又受到来自CreateNamedPipe&co的MSDN样本的严重影响 ] :

服务器端:

HANDLE hPipe = INVALID_HANDLE_VALUE;
bool bConnected = false;

 hPipe = CreateNamedPipe( L"\\\\.\\pipe\\nhsupspipe",
                          PIPE_ACCESS_DUPLEX,
                          PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                          PIPE_UNLIMITED_INSTANCES,
                          sizeof( Message ),
                          0,
                          0,
                          NULL );

 // failed to create pipe?
 if( hPipe == INVALID_HANDLE_VALUE ){
   return -1;
 }

 // Wait for the client to connect; if it succeeds, 
 // the function returns a nonzero value. If the function
 // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 
 bConnected = ConnectNamedPipe( hPipe, NULL ) ? true : ( GetLastError() == ERROR_PIPE_CONNECTED );

 if( bConnected ){
  while( true ){ 
   unsigned long ulBytesRead = 0;
   // read client requests from the pipe. 
   bool bReadOk = ReadFile( hPipe,
                            &message,
                            sizeof( message ),
                            &ulBytesRead,
                            NULL );

   // bail if read failed [error or client closed connection]
   if( !bReadOk || ulBytesRead == 0 )
    break;

   // all ok, process the message received

  }
 }
 else{
   // the client could not connect, so close the pipe. 
   CloseHandle( hPipe );
 }

 return 0;
Run Code Online (Sandbox Code Playgroud)

客户端:

HANDLE hPipe = INVALID_HANDLE_VALUE;

 // create the named pipe handle
 hPipe = CreateFile( L"\\\\.\\pipe\\nhsupspipe",
                     GENERIC_READ | GENERIC_WRITE,
                     0, 
                     NULL, 
                     OPEN_EXISTING,
                     0,
                     NULL );

 // if everything ok set mode to message mode
 if( INVALID_HANDLE_VALUE != hPipe ){
  DWORD dwMode = PIPE_READMODE_MESSAGE;
  // if this fails bail out
  if( !SetNamedPipeHandleState( hPipe, &dwMode, NULL, NULL ) ){
   CloseHandle( hPipe ); 

   return -1;
  }
 }

 unsigned long ulBytesWritten = 0;
 bool bWriteOk = WriteFile( hPipe, 
                            ( LPCVOID )&message, 
                            sizeof( Message ), 
                            &ulBytesWritten, 
                            NULL );

 // check if the writing was ok
 if( !bWriteOk || ulBytesWritten < sizeof( Message ) ){
  return -1;
 }

 // written ok

 return 0;
Run Code Online (Sandbox Code Playgroud)

上面提到的消息是一个结构,它将是您可能想要打包的消息.

因为在您的场景中,客户端(服务)可能会在服务器(通知程序)之前启动并运行,您需要在客户端实现某种重新连接策略.

稍微不同的是,你应该仔细考虑奥斯特曼先生在回答中所说的话(即使只是因为他是拉里奥斯特曼).