命名管道读取超时

Named-pipe reading timeout

本文关键字:超时 读取 管道      更新时间:2023-10-16

我正在尝试为命名管道的读取操作设置超时。
为了从命名管道读取,我正在使用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方法不应该与管道一起使用?还有其他方法可以获取读取超时吗?

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

不能将 SetCommTimeouts 与命名管道一起使用。如果需要超时,则必须使用异步 I/O 并使用CancelIoCancelIoEx

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