简体   繁体   English

通过重叠的IO进行异步命名Windows管道通信

[英]Asynchronous named Windows pipe communication via overlapped IO

I'm using overlapped IO to read and write a single Windows pipe in C code simultantiously. 我正在使用重叠的IO来同时用C代码读取和写入单个Windows管道。 I want to write a synchronous function to read and write data from seperate threads. 我想编写一个同步函数,以从单独的线程读取和写入数据。 If you are using synchronous IO you cannot read and write the pipe simultaniously. 如果使用同步IO,则无法同时读取和写入管道。 My client and my server are using the same write/read functions. 我的客户端和服务器使用相同的写入/读取功能。 Time by time my client sends data that is never received by the server. 我的客户每次发送服务器从未接收到的数据。 Does anyone have an idea how this could happen? 有谁知道这将如何发生? If I use synchronous IO in the client everything works as expected. 如果我在客户端中使用同步IO,那么一切都会按预期进行。

The server pipe is opened by the following cmd: 通过以下cmd打开服务器管道:

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); 

The client pipe is opend this way: 客户端管道以这种方式打开:

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

I'm using these read function: 我正在使用以下读取功能:

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;
}

And last but not least the write function: 最后但并非最不重要的是write函数:

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;
}

The documentation for ReadFile says: ReadFile的文档说:

If hFile was opened with FILE_FLAG_OVERLAPPED , the following conditions are in effect: 如果使用FILE_FLAG_OVERLAPPED打开hFile ,则以下条件有效:

The lpNumberOfBytesRead parameter should be set to NULL . lpNumberOfBytesRead参数应设置为NULL Use the GetOverlappedResult function to get the actual number of bytes read. 使用GetOverlappedResult函数获取读取的实际字节数。

This applies even if the operation completes synchronously. 即使操作同步完成,这也适用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM