2017-03-24 6 views
0

重複したIOを使用して、Cコードで単一のWindowsパイプを同時に読み書きします。私は、別々のスレッドからデータを読み書きするための同期関数を書いています。同期I/Oを使用している場合は、パイプを読み書きできません。私のクライアントと私のサーバーは同じ書き込み/読み取り機能を使用しています。クライアントがサーバーで受信できないデータを送信することが時々あります。どのように起こるか考えている人はいますか?クライアントで同期IOを使用すると、すべてが期待通りに機能します。オーバーラップされたIOを介した非同期のWindowsパイプ通信

CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 

私は、これらのリード機能使用しています:

int readBytesPipeCommChannel(PipeCommChannelData* comm, uint32_t* amount) 
    OVERLAPPED osRead; 
    memset(&osRead, 0, sizeof(osRead)); 
    osRead.hEvent = comm->readAsyncIOEvent; 

    int err = 0; 
    if(!ReadFile(comm->pipeH, comm->receiveBuffer, sizeof(comm->receiveBuffer), amount, &osRead)) 
    { 
     err = GetLastError();  
     if (err == ERROR_IO_PENDING) 
     { 
      if(WaitForSingleObject(osRead.hEvent, INFINITE)) 
      { 
       GetOverlappedResult(comm->pipeH, &osRead, amount, TRUE); 
      } 
      else 
      { 
       CancelIo(comm->pipeH); 
       return PIPE_EVENT_ERROR; 
      } 
     } 
     else if(err != ERROR_BROKEN_PIPE) 
     { 
      return PIPE_READ_ERROR; 
     } 
    } 
    if(err == ERROR_BROKEN_PIPE) 
     return PIPE_BROKEN_ERR; 

    return PIPE_OK; 
} 
をクライアントパイプがこのようにオープンしましれる

CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 
             instances, PIPE_BUF_SIZE, PIPE_BUF_SIZE, 0, NULL); 

サーバーパイプには、以下のcmdで開かれました

最後に、書き込み機能:

int sendBytesPipeCommChannel(PipeCommChannelData* comm, const uint8_t* bytes, uint32_t amount) 
{ 
    OVERLAPPED osWrite; 
    memset(&osWrite, 0, sizeof(osWrite)); 
    osWrite.hEvent = comm->writeAsyncIOEvent; 

    uint32_t bytesWritten = 0; 
    for(uint32_t curPos = 0; curPos < amount; curPos += bytesWritten) 
    { 
     if(!WriteFile(comm->pipeH, &bytes[curPos], (amount - curPos), &bytesWritten, &osWrite)) 
     { 
      if (GetLastError() != ERROR_IO_PENDING) 
       return PIPE_WRITE_ERR; 

      if(!WaitForSingleObject(osWrite.hEvent, INFINITE)) 
      { 
       CancelIo(comm->pipeH); 
       return PIPE_EVENT_ERROR; 
      } 
     } 
    } 
    return PIPE_OK; 
} 
+0

ReadFileのGetOverlappedResult関数をReadFileから移動すると、コンテキストが動作するようになります。しかし、なぜ私は理解していない。私は調査を続ける。 –

答えて

0

ReadFile関数のドキュメントは言う:hFileFILE_FLAG_OVERLAPPEDで開かれた場合

、次の条件が有効である:

lpNumberOfBytesReadパラメータがNULLに設定する必要があります。読み取られた実際のバイト数を取得するには、GetOverlappedResult関数を使用します。

これは、操作が同期して完了した場合でも適用されます。

+0

はいこれは動作を説明しています。ヒントありがとうございます。 –

関連する問題