如何随时(同时)在Windows中发送数据?

时间:2019-01-13 14:41:40

标签: c asynchronous winapi ipc named-pipes

我想在Windows OS中编写一个命名管道客户端,即使客户端正在接收数据,它也可以随时发送数据。MSDN的Example仅显示接收到某些内容后发送数据。而串行操作不是我想要。因为我在客户端和服务器之间传输的数据不是很大,也就是说,IO操作不应该是一个耗时的过程,所以我没有在客户端中使用OVERLAP

我在MSDN客户端示例中修改的代码如下: 主线程继续读取数据,子线程继续向服务器发送数据。但是,调试时服务器在读取数据时阻塞。

std::thread t([&] {
    cbToWrite = (lstrlen(lpvMessage) + 1) * sizeof(TCHAR);
    _tprintf(TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage);


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

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

    printf("\nMessage sent to server, receiving reply as follows:\n");

});

while (1)   // main thread always reading
{
    do
    {
        // Read from the pipe.

        fSuccess = ReadFile(
            hPipe,    // pipe handle
            chBuf,    // buffer to receive reply
            BUFSIZE * sizeof(TCHAR),  // size of buffer
            &cbRead,  // number of bytes read
            NULL);    // not overlapped

        if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
            break;

        _tprintf(TEXT("\"%s\"\n"), chBuf);
    } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA

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


t.join();

我希望有人可以纠正该代码以使其正常工作,或者您能说出标准做法或建议吗? 非常感谢!

1 个答案:

答案 0 :(得分:1)

来自CreateFile文档的

关于 FILE_FLAG_OVERLAPPED

  

如果指定了此标志,则该文件可以用于同时   读写操作。

     

如果未指定此标志,则将对I / O操作进行序列化

I / O操作被序列化意味着新的I / O请求将等待直到之前的I / O操作未完成。因此,即使您不使用FILE_FLAG_OVERLAPPED,即使在此处使用多个线程也无济于事。例如,您可以从一个线程开始读取操作,然后等待直到数据不存在。如果您从另一个线程调用此文件的写操作-将在I / O子系统代码中等待写操作,直到读取未完成。即使您说出查询文件名(通过GetFileInformationByHandleExFileNameInfo),该请求也会被序列化并等待读取未完成。

创建文件时,同时进行I / O操作(不仅是读写操作,而且所有操作)的唯一选项使用FILE_FLAG_OVERLAPPED