Named-pipe reading timeout

2019-02-25 06:59发布

I'm trying to set a timeout to the reading operation of my named pipe.
In order to read from the named pipe, I'm using the ReadFile function.
I read that a timeout can be set for this function with the SetCommTimeouts function but when I try to use it, I get system error 1: "Incorrect function".
Here is my code (this is the client side):

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

Am I doing something wrong or the SetCommTimeouts method is not supposed to be used with pipes? Is there any other way to get a reading timeout?

3条回答
啃猪蹄的小仙女
2楼-- · 2019-02-25 07:12

ReadFile blocks until it read requested amount of bytes or error/abort happen. Overlapped works same, i.e. it completes on same conditions. Tried to implement timeouts using CancelIoEx and figured out that it loses data. Until now see no way to implement timeouts and read only part of requested amount of bytes, or read cached data.

查看更多
贪生不怕死
3楼-- · 2019-02-25 07:16

If the purpose of the timeout is to not get stuck forever you may consider a call to PeekNamedPipe(...) in a timed loop. This way you can check whether there is anything to read from time to time. Alternatively PeekNamedPipe may be used to decide whether a read on the pipe is actually going to get anything before the read is performed. This way a "waiting" read can be avoided.

查看更多
我想做一个坏孩纸
4楼-- · 2019-02-25 07:31

You cannot use SetCommTimeouts with named pipes. If you want timeouts, you will have to use Async I/O and implement the timeout yourself using CancelIo or CancelIoEx

查看更多
登录 后发表回答