1

パイプで文字列を渡す必要があります。パイプでポインターを渡すことはできず、データを渡す必要があります。文字列を渡すために、文字の配列を送信できます。しかし、私は配列を使いたくありません。文字列を可変サイズで送信する方法が必要です。

パイプ サーバーとパイプ クライアントを作成するために msdn サンプルを使用しました。

しかし、パイプ クライアントとパイプ サーバーで writeFile 関数と readFile 関数を 1 つだけ使用する代わりに、次のように 3 回使用しました。

文字列のサイズを保存するために構造体を使用しました。まず、この構造が送信されます。その後、私の 2 つの文字列が送信されます。したがって、最初にパイプサーバーで文字列のサイズが読み取られ、その後2つの文字列が受信されます。

クライアント プログラムとサーバー プログラムの両方で、次のような構造を定義しました。

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 に答える