Windows中的命名管道

Posted

技术标签:

【中文标题】Windows中的命名管道【英文标题】:Named pipe in windows 【发布时间】:2014-10-20 09:53:37 【问题描述】:

我正在尝试通过命名管道实现两个进程之间的通信。更准确地说(不要认为它会影响问题),我希望两个 Matlab 实例能够相互通信。

到目前为止一切正常,但在 10% 的情况下,它表示管道末端还有另一个进程...

到目前为止我的代码(缩短)(发件人):

pipe = CreateNamedPipe(uniquePipeName, // name of the pipe
    PIPE_ACCESS_DUPLEX, // 
    PIPE_TYPE_MESSAGE, // send data as a byte stream
    1, // only allow 1 instance of this pipe
    0, // no outbound buffer
    0, // no inbound buffer
    0, // use default wait time
    NULL // use default security attributes
    );
... some error handling...
result = ConnectNamedPipe(pipe, NULL);
if(!result)

    printerror()
    CloseHandle(pipe);
    return;

numBytesWritten = 0;
printf("Sending %lg\n", *uPtrs[0]);
result = WriteFile(pipe, // handle to our outbound pipe
    uPtrs[0], // data to send
    sizeof(double),

    &numBytesWritten, // will store actual amount of data sent
    NULL // not using overlapped IO
    );
if (!result) 
    printerror()

CloseHandle(pipe);

接收者:

    while(true)

    if (!WaitNamedPipe(uniquePipeName, NMPWAIT_USE_DEFAULT_WAIT))
        continue;   // timeout, try again
    pipe = CreateFile(
        uniquePipeName,
        GENERIC_READ, // only need read access
        0,//FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
        );
    if (pipe != INVALID_HANDLE_VALUE)
        break;
    else
    
        
            if (GetLastError() == ERROR_PIPE_BUSY || GetLastError() == 2)
            
                FormatMessage(
                    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    GetLastError(),
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    (LPTSTR) &lpMsgBuf,
                    0, NULL );
                printf("%s\n",lpMsgBuf);
                CloseHandle(pipe);
                if (!WaitNamedPipe(uniquePipeName, NMPWAIT_USE_DEFAULT_WAIT))
                    continue;   // timeout, try again
            
            else
            
                printf("Failed to connect pipe. Error %.i\n",GetLastError());
                y[0] = 0;
                return;
            
            //system("pause");
        
    

printf("Connected!\n");

result = ReadFile(
    pipe,
    &buffer_in, // the data from the pipe will be put here
    sizeof(double),
    //        127 * sizeof(wchar_t), // number of bytes allocated
    &numBytesRead, // this will store number of bytes actually read
    NULL // not using overlapped IO
    );


printf("Recieved: %lg\n",buffer_in);
printf("Recieved: %lg\n", buffer_out);

y[0] = buffer_in;
CloseHandle(pipe);

提交失败的错误码是:GetLastError: 535 : There is an process on the other end of the pipe.

由于我对整个主题完全陌生,因此感谢任何其他改进核心的建议。

非常感谢!

【问题讨论】:

你不会在任何地方调用 DisconnectNamedPipe 来清理东西 好电话,谢谢。我认为 CloseHandle 会处理它。可悲的是,它并没有解决问题。 【参考方案1】:

我知道这个问题来自 2014 年,但我遇到了同样的问题并找到了解决方案。 在 Microsoft 文档示例 (https://docs.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server) 中,您可以看到他们检查您收到的确切错误消息 (535),在这种情况下 fConnected 设置为 true 并且程序继续。所以我猜这个错误实际上是成功的?

fConnected = ConnectNamedPipe(hPipe, NULL) ? 
     TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

【讨论】:

感谢您隔了这么久才讨论这个话题!我的代码不再存在,所以我无法测试它。但如果其他人有同样的问题,他们可能会在这里找到答案。

以上是关于Windows中的命名管道的主要内容,如果未能解决你的问题,请参考以下文章

适用于 Windows 和 Linux 的 Go 中的命名管道

无法在 Windows 7 中的命名管道内创建进程

Windows 中的 python 2 和 python 3 之间的命名管道的工作方式有啥不同吗?

从底层的角度来看,Windows 中的命名管道和远程过程调用 (RPC) 有啥区别?

使用 App.Config 在 Windows 服务中的 WCF 命名管道

windows命名管道