【问题标题】:Named-pipe reading timeout命名管道读取超时
【发布时间】:2012-11-25 22:05:52
【问题描述】:

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

【问题讨论】:

    标签: c++ windows timeout named-pipes


    【解决方案1】:

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

    【讨论】:

    • 你是英雄。
    【解决方案2】:

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

    【讨论】:

    • 您能否解释一下,为什么不能对命名管道使用超时或提供此知识来源的链接?
    • 不幸的是,答案是:“因为你做不到:API 不允许这样做。”我希望我有一个更好、更深入的答案给你,唉,我没有。您可能想阅读this MSDN page。底线:如果你想要“超时”,你需要使用重叠 I/O。
    • 好的,谢谢。我考虑使用 PeekNamedPipe,但代码“正在建设中”。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多