3

我正在尝试为我的命名管道的读取操作设置超时。
为了从命名管道中读取,我正在使用该ReadFile函数。
我读到可以使用该SetCommTimeouts功能为此功能设置超时,但是当我尝试使用它时,我收到系统错误 1:“功能不正确”。
这是我的代码(这是客户端):

m_pipe = CreateFileA(pipeName,   // pipe name 
                         GENERIC_READ |  // read and write access 
                         GENERIC_WRITE, 
                         0,              // no sharing 
                         NULL,           // default security attributes
                         OPEN_EXISTING,  // opens existing pipe 
                         0,              // default attributes 
                         NULL);          // no template file 

    if (m_pipe != INVALID_HANDLE_VALUE)
    {
            DWORD mode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
            ok = SetNamedPipeHandleState(m_pipe, &mode, NULL, NULL);
            COMMTIMEOUTS cto;
            cto.ReadTotalTimeoutConstant = 1000;
            BOOL time = SetCommTimeouts(m_pipe, &cto);
    }

我做错了什么还是该SetCommTimeouts方法不应该与管道一起使用?有没有其他方法可以获得阅读超时?

4

3 回答 3

15

如果超时的目的是为了不卡住,您可以考虑在定时循环中forever调用PeekNamedPipe(...) 。这样,您可以不时检查是否有要阅读的内容。或者PeekNamedPipe,可用于在执行读取之前决定管道上的读取是否实际上会得到任何东西。这样可以避免“等待”读取。

于 2012-12-08T16:49:21.767 回答
3

您不能将 SetCommTimeouts 与命名管道一起使用。如果您想要超时,您将不得不使用异步 I/O 并自己使用CancelIo或实现超时CancelIoEx

于 2012-12-07T17:30:44.680 回答
2

ReadFile 阻塞,直到它读取请求的字节数或发生错误/中止。重叠的工作方式相同,即它在相同的条件下完成。尝试使用 CancelIoEx 实现超时并发现它会丢失数据。到目前为止,还没有办法实现超时并只读取部分请求的字节数,或者读取缓存的数据。

于 2016-01-19T08:11:23.933 回答