首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >命名管道无法第二次连接

命名管道无法第二次连接
EN

Stack Overflow用户
提问于 2017-02-15 15:41:05
回答 1查看 848关注 0票数 0

我有一个客户机-服务器管道进程,当我第一次尝试连接时,一切正常,但是当我再次启动客户机进程而不重新启动服务器时,我无法使用PIPE_BUSY错误连接,尽管GetOverlappedResult在服务器上成功,但是等待对象并不表示有人连接了,当然消息是空的。

代码语言:javascript
复制
std::wstring buffer;
while (true) {
    // pinging here...
    DWORD result = WaitForSingleObject(hEvent, 2000);

    if (result == WAIT_FAILED) {
        std::wcout << result << std::endl;
        break;
    }

    if (result == WAIT_TIMEOUT) {
        // always here 
    }

    ResetEvent(hEvent);

    DWORD bytesTransferred;

    OVERLAPPED ov;
    ZeroMemory( & ov, sizeof(OVERLAPPED));
    ov.hEvent = hEvent;

    if (GetOverlappedResult(pipe(), & ov, & bytesTransferred, TRUE) == 0) // FAILED
    {
        return; // we do never get here...
    } else {
        ZeroMemory( & ov, sizeof(OVERLAPPED));

        DWORD bytesToRead = 0;

        BOOL pingPipe;

        Timer timer(1000);

        while (!bytesToRead || !pingPipe) {
            if (!timer.in()) {
                break;
            }

            pingPipe = PeekNamedPipe(pipe(), NULL, 0, NULL, & bytesToRead, NULL);
        }

        buffer.resize(sizeof(TCHAR) * bytesToRead);

        if (!ReadFile(pipe(), & buffer[0], bytesToRead, & bytesTransferred, & ov) && timer.in()) {
            if (GetLastError() == ERROR_IO_PENDING) {
                continue;
            }

            return;
        }

        // data here
        std::wcout << buffer << std::endl;
    }
}

DisconnectNamedPipe(pipe());
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-15 16:05:56

我不清楚hEvent是什么,因为您遗漏了所有初始化代码,但是您使用GetOverlappedResult不正确,而且所有的赌注在这一点上几乎都是不正确的:

代码语言:javascript
复制
OVERLAPPED ov;
ZeroMemory( & ov, sizeof(OVERLAPPED));
ov.hEvent = hEvent;

if (GetOverlappedResult(pipe(), & ov, & bytesTransferred, TRUE) == 0) ...

你不是这样做的。您不需要声明一个OVERLAPPED并将它传递给GetOverlappedResult。实际上,您必须启动一个重叠操作(读、写、连接等),例如首先将OVERLAPPED传递给ReadFile或其他东西。而您给出的事件句柄通常是您创建的一个事件,它专门用于这个重叠的任务,而不是其他任何东西都在使用的事件。

就像你走到街上随便一个陌生人跟前,突然说:“那么,你拿到我要的东西了吗?”

您正在尝试完成一个尚未启动的重叠操作,并且使用一个事件句柄,您可能也要使用该句柄来检查传入的连接或其他东西。所以,这几乎是在空气中将要发生的事情。

所以你有两个选择:

  1. 阅读本教程 (我还没有验证它的正确性,但乍一看它很好)、对重叠I/O的概述具有重叠I/O的命名管道服务器的MS示例,然后再读一遍,直到您理解为止,或者
  2. 停止使用重叠的I/O,这是我现在建议的,只是为了降低概念。

除了上述之外,您的客户端还可能会出现更多的问题,但是您还没有显示相应的代码。您可能需要在相关的文档中重复检查它,以确保在这一端一切都正常。同样,就缺失的代码而言,您希望通过在创建时传递适当的标志来验证在服务器端以重叠模式创建管道(无法查找,在电话上进行此编辑,但请检查管道创建api文档)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42253793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档