c - 命名管道消息损坏 (Win32,C)

标签 c winapi named-pipes

我有一些管道通信代码 - 接收到的字节与发送的字节不匹配。 有一个循环,其中调用“CallNamedPipe”将消息发送到服务器。 现在只有第一条消息被完整接收,所有其余消息都被​​部分填充为 0xCD 字节。 看来,当我在发送后释放内存时 - 服务器线程仍在读取它。 MSDN 说 CallNamedPipe() 是一个完整的消息序列:打开管道、发送字节和关闭管道。 所以,这对我来说似乎很奇怪。我必须提到,这段代码是由 VC++ 6.0 构建的——一个非常古老的编译器。代码在 Windows 7 上运行,也许我需要使用兼容模式?客户端和服务器可执行文件都在同一物理系统上运行,而不是远程运行。客户端在启动时使用 CreateProcess() 来启动服务器。这些消息会在很晚的时候发送,所以我希望比赛条件应该无关紧要。

感谢您的任何建议。

============ Client side (pseudocode): ============
for (iPiece=0; iPiece < nPieces; ++iPiece)
{
    buffer = malloc (2048);

    // copy some data bytes into buffer (1..2048 bytes)
    // log 1st 32 DWORDS from message about to be sent

    if (! CallNamedPipe (name, buffer, nBytes, ..., 1000))
    {
        // diagnostics: call to GetLastError(), etc.
    }
    free (buffer);
}

============ Server side (pseudocode): ============
DWORD __stdcall ServerThreadProc (PVOID p)
{
    UINT    cbMaxMsg = 0x10000; // 64K for a pipe message
    PVOID   buffer = malloc (cbMaxMsg);
    HANDLE  hPipe;
    BOOL    fAbort = 0;

    hPipe = CreateNamedPipe (name, PIPE_ACCESS_DUPLEX,
        PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
        PIPE_UNLIMITED_INSTANCES, cbMaxMsg, cbMaxMsg, 1000, NULL);

    while (fAbort == 0) // one of pipe messages sets fAbort=1, so thread can return.
    {
        if (ConnectNamedPipe (hPipe, NULL))
        {
            DWORD   bytesLoaded = 0;

            ReadFile (hPipe, buffer, cbMaxMsg, &bytesLoaded, NULL);
            if (bytesLoaded)
            {
                // log 1st 32 DWORDS from received message
                // process the pipe message (switch/case)
                // data may be written back to client after processing

                FlushFileBuffers (hPipe);
            }
            DisconnectNamedPipe (hPipe);
        }
        else
        {
            // diagnostics, GLE(), etc.
        }
    }

    free (buffer);
    CloseHandle (hPipe);
    return 0;
}

最佳答案

使用 PIPE_TYPE_MESSAGE 使管道成为消息管道。它将向服务器提供类似行为的消息。如果您尝试阅读超过标准邮件大小的内容,它将为您提供完整的邮件。

0xCD 是标准填充,我认为是堆的,但不确定。

到目前为止,我们正在读取 64k 的数据,并写入 2k 的数据。看起来 CallNamedPipe 在数据被接受之前不会返回(因为有超时 - 设置为 1000ms)。这些系统的行为是,一旦内核拥有数据缓冲区,则不允许客户端代码更改内存。

我会说最有可能的情况是缓冲区未正确填充,并且服务器中的数据量与管道中的消息一致。

您没有提供足够的数据来验证这一点。

关于c - 命名管道消息损坏 (Win32,C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35209319/

相关文章:

关于 malloc array of struct 的困惑

c++ - 在各自的线程上运行多个对象似乎多次运行同一个对象

windows - 双工命名管道在某个写入时挂起

c - 弹性 Action 在什么范围内执行?

c - windows下c下socket编程测试从本地主机接收

c - 段错误,地址越界

c++ - 带投影的无边框窗口

c++ - 应用程序窗口中的光标类型不正确

.net - 如何从另一个 .NET 进程获取对象的句柄?

.net - C+C# 进程间通信 : Named Pipes, 内存映射文件还是其他?