1

我需要通过管道传递一些字符串。我们不能通过管道传递指针,我们必须传递数据。为了传递一个字符串,我们可以发送一个字符数组。但我不想使用数组。我需要一种以可变大小发送字符串的方法。

我使用 msdn 示例来创建管道服务器和管道客户端:

但是在管道客户端和管道服务器中,我不是只有一个 writeFile 和 readFile 函数,而是以这种方式使用了它们三次:

我使用了一个结构来保存我的字符串大小。首先发送这个结构。然后我的两个字符串将被发送。所以首先在管道服务器中,将读取字符串的大小,然后接收两个字符串。

我在客户端和服务器程序中都定义了这样的结构:

typedef struct 
{
    int fileNameLen;
    int commandArgLen;
}pipeData,*PpipeData;

   pipeData dataToWrite;
   pipeData *pdataToWrite = &dataToWrite;

在管道客户端我想发送这个字符串:

   LPTSTR s1 = TEXT("file1");
   LPTSTR s2 = TEXT("startCmd");

   dataToWrite.commandArgLen = sizeof(s1);
   dataToWrite.fileNameLen = sizeof(s2);

我以这种方式通过管道客户端发送了结构。

   fSuccess = WriteFile( 
      hPipe,                  // pipe handle 
      pdataToWrite,             // message 
      sizeof(dataToWrite),              // message length 
      &cbWritten,             // bytes written 
      NULL);                  // not overlapped 

   if ( ! fSuccess) 
   {
      _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() ); 
      return -1;
   }

   fSuccess = WriteFile( 
      hPipe,                  // pipe handle 
      s1,             // message 
      sizeof(s1),     // message length 
      &cbWritten,             // bytes written 
      NULL);                  // not overlapped 

   if ( ! fSuccess) 
   {
      _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() ); 
      return -1;
   }


   fSuccess = WriteFile( 
      hPipe,                  // pipe handle 
      s2,             // message 
      sizeof(s2),     // message length 
      &cbWritten,             // bytes written 
      NULL);                  // not overlapped 

   if ( ! fSuccess) 
   {
      _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() ); 
      return -1;
   }

在管道服务器中读取管道我使用 3 readFile 像这样:

      fSuccess = ReadFile( 
         hPipe,        // handle to pipe 
         pdataToWrite,    // buffer to receive data 
         sizeof(pdataToWrite), // size of buffer 
         &cbBytesRead, // number of bytes read 
         NULL);        // not overlapped I/O 

      if (!fSuccess || cbBytesRead == 0)
      {   
          if (GetLastError() == ERROR_BROKEN_PIPE)
          {
              _tprintf(TEXT("InstanceThread: client disconnected.\n"), GetLastError());
              break;
          }

          else
          {
              _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.\n"), GetLastError());
              break;
          }

      }

   // Process the incoming message.
      GetAnswerToRequest(TEXT("structure recieved"), pchReply, &cbReplyBytes); 



      fSuccess = ReadFile( 
         hPipe,        // handle to pipe 
         s1,    // buffer to receive data 
         dataToWrite.commandArgLen, // size of buffer 
         &cbBytesRead, // number of bytes read 
         NULL);        // not overlapped I/O 

      if (!fSuccess || cbBytesRead == 0)
      {   
          if (GetLastError() == ERROR_BROKEN_PIPE)
          {
              _tprintf(TEXT("InstanceThread: client disconnected.\n"), GetLastError()); 
          }

          else
          {
              _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.\n"), GetLastError()); 
          }
          break;
      }    
      GetAnswerToRequest(s1, pchReply, &cbReplyBytes); 


      fSuccess = ReadFile( 
         hPipe,        // handle to pipe 
         s2,    // buffer to receive data 
         dataToWrite.fileNameLen, // size of buffer 
         &cbBytesRead, // number of bytes read 
         NULL);        // not overlapped I/O 

      if (!fSuccess || cbBytesRead == 0)
      {   
          if (GetLastError() == ERROR_BROKEN_PIPE)
          {
              _tprintf(TEXT("InstanceThread: client disconnected.\n"), GetLastError()); 
          }

          else
          {
              _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.\n"), GetLastError()); 
          }
          break;
      }



      GetAnswerToRequest(s2, pchReply, &cbReplyBytes); 

这种方式不能正常工作。当管道服务器在第一个 readFile 中读取数据时,它可能会返回此错误:ERROR_MORE_DATA(如果我在 createNamedPipe 中使用了 PIPE_TYPE_MESSAGE)

我不知道如何在管道客户端和服务器中使用多个 writeFile 和 readFile。

4

1 回答 1

1

如果在消息模式下读取命名管道并且下一条消息比 nNumberOfBytesToRead 参数指定的长,ReadFile 返回 FALSE,GetLastError 返回 ERROR_MORE_DATA。可以通过对 ReadFile 或 PeekNamedPipe 函数的后续调用来读取消息的其余部分。通过 MSDN

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx

供参考

于 2013-09-03T06:38:34.517 回答