WriteFile() 块(通过命名管道从 C++ 客户端写入 C# 服务器)

Posted

技术标签:

【中文标题】WriteFile() 块(通过命名管道从 C++ 客户端写入 C# 服务器)【英文标题】:WriteFile() blocks (writing from C++ client to C# server via named pipe ) 【发布时间】:2011-05-18 08:03:45 【问题描述】:

我被困在这里,请帮助。 我有一个 C# 命名的管道服务器,管道由以下人员创建:

new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads);

在 C++ 中,我这样创建了客户端:

        m_hPipe = CreateFile( 
        strPipeName,            // Pipe name 
        GENERIC_READ |  GENERIC_WRITE,  // Read and write access 
        0,              // No sharing 
        NULL,               // Default security attributes
        OPEN_EXISTING,          // Opens existing pipe 
        FILE_FLAG_OVERLAPPED,    
        NULL);  

我将管道类型设置为PIPE_READMODE_BYTE | PIPE_TYPE_BYTE 我编写了一个函数 WriteString() 来将字符串写入管道。函数大致是这样的:

    // Write the length of the string to the pipe (using 2 bytes)
    bool bResult = WriteFile(m_hPipe, buf, 2, &cbBytesWritten, NULL);

    // Write the string itself to the pipe
    bResult = WriteFile(m_hPipe, m_chSend, len, &cbBytesWritten, NULL);

    // Flush the buffer
    FlushFileBuffers(m_hPipe);

我对该函数进行了两次调用:

    WriteString(_T("hello server!"));   // message sent and the server saw it correctly
    WriteString(_T("goodbye server!")); // message not sent, coz WriteFile() blocked here

现在的问题是:程序在第二个 WriteString() 调用中的第一个 WriteFile() 调用中被阻塞。 只有当管道被服务器关闭时,WriteFile() 调用才能返回错误。

这是可靠的可重现的。

是什么阻止了 WriteFile() 调用?我已经在使用 OVERLAPPED 文件标志。 管道缓冲区已满?我一直从服务器端的管道读取数据。

非常感谢!

【问题讨论】:

【参考方案1】:

FILE_FLAG_OVERLAPPED 启用异步 I/O。它不会自动使任何操作异步、非阻塞或缓冲。

您需要使用WriteFile 的第5 个参数——传入OVERLAPPED 结构,在完成时设置一个事件,或者将文件句柄与I/O Completion Port 关联。

【讨论】:

以上是关于WriteFile() 块(通过命名管道从 C++ 客户端写入 C# 服务器)的主要内容,如果未能解决你的问题,请参考以下文章

如何在管道上使用 WriteFile 修复乱码文本?

命名管道问题

fprintf vs WriteFile 写入管道:无法从所有管道读取

使用命名管道将图像从 C++ 发送到 C# 应用程序

如何使用命名管道从 C++ 调用 WCF 方法?

Linux。 Python。从命名管道读取