2017-03-24 11 views
0

중복 된 IO를 사용하여 단일 Windows 파이프를 C 코드로 동시에 읽고 쓸 수 있습니다. 별도의 스레드에서 데이터를 읽고 쓰는 동기 함수를 작성하려고합니다. 동기 IO를 사용하는 경우 파이프를 읽고 쓸 수 없습니다. 클라이언트와 서버가 동일한 쓰기/읽기 기능을 사용하고 있습니다. 내 클라이언트가 서버에서 수신하지 못하는 데이터를 보내는 시간 어떻게 이런 일이 일어날 지 생각할 사람이 있습니까? 클라이언트에서 동기 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; 
} 
을 클라이언트 관이 방법에 opend입니다

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에 대한 문서는 말한다 :

hFile 경우가 FILE_FLAG_OVERLAPPED와 연, 다음과 같은 조건이 적용됩니다 :

lpNumberOfBytesRead 매개 변수는 NULL로 설정해야합니다. GetOverlappedResult 함수를 사용하여 읽은 실제 바이트 수를 얻습니다.

작업이 동 기적으로 완료되는 경우에도 적용됩니다.

+0

예 이것은 동작을 설명합니다. 힌트를 가져 주셔서 감사합니다. –