1

命名管道服务器是用

hPipe = CreateNamedPipe( zPipePath,
                         PIPE_ACCESS_DUPLEX,
                         PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE,
                         PIPE_UNLIMITED_INSTANCES,
                         8192, 8192, NMPWAIT_USE_DEFAULT_WAIT, NULL)

然后我们立即调用:

ConnectNamedPipe( hPipe, BYVAL %NULL )

在客户端连接之前阻塞。

然后我们直接进入 ReadFile( hPipe, ...

问题是客户端需要有限的时间来准备和写入所有 fcgi 请求参数。这通常在 Pipe Server 执行其 ReadFile() 之前尚未完成。因此,读取文件操作在管道中找不到任何数据,并且该过程失败。

在客户端连接到 NamedPipe 后,是否有一种机制来判断 Write() 何时发生/完成?

如果我可以控制客户端进程,我可以使用一个普通的互斥锁,但我没有,我真的不想为了解决这个问题而进入 I/O 完成端口!

我当然可以使用一个简单的计时器来等待 60m/s 左右,这通常是足够的时间来完成写入,但这是一个可怕的 hack。

4

1 回答 1

4

我不确定您使用的是什么语言 - 我不认识这样的表达

PIPE_TYPE_BYTE OR %PIPE_WAIT OR %PIPE_READMODE_BYTE

但在我看来,服务器的 ReadFile() 应该阻塞,直到客户端写入数据。

看起来不正确(但不应该伤害任何东西)的一件事是使用NMPWAIT_USE_DEFAULT_WAIT- 该值是供客户在调用时使用的WaitNamedPipe()

你能看看这 2 个 C++ 程序是否像你期望的那样交互(即,服务器阻塞直到客户端写东西)?我从 Jones/Ohlund 的“Windows 网络编程”一书中获取了这些程序。服务器ReadFile()按预期阻止了我的调用:

- 服务器.cpp

// Server.cpp

#include <windows.h>
#include <stdio.h>

void main(void)
{
    HANDLE PipeHandle;
    DWORD BytesRead;
    CHAR buffer[256];
    if ((PipeHandle = CreateNamedPipe("\\\\.\\Pipe\\Jim",
        PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1,
        0, 0, 1000, NULL)) == INVALID_HANDLE_VALUE)
    {
        printf("CreateNamedPipe failed with error %d\n",
            GetLastError());
        return;
    }

    printf("Server is now running\n");

    if (ConnectNamedPipe(PipeHandle, NULL) == 0)
    {
        printf("ConnectNamedPipe failed with error %d\n",
            GetLastError());
        CloseHandle(PipeHandle);
        return;
    }

    if (ReadFile(PipeHandle, buffer, sizeof(buffer),
        &BytesRead,  NULL) <= 0)
    {
        printf("ReadFile failed with error %d\n", GetLastError());
        CloseHandle(PipeHandle);
        return;
    }

    printf("%.*s\n", BytesRead, buffer);

    if (DisconnectNamedPipe(PipeHandle) == 0)
    {
        printf("DisconnectNamedPipe failed with error %d\n",
            GetLastError());
        return;
    }

    CloseHandle(PipeHandle);
}

- 客户端.cpp

// Client.cpp

#include <windows.h>
#include <stdio.h>

#define PIPE_NAME "\\\\.\\Pipe\\jim"

void main(void)
{
    HANDLE PipeHandle;
    DWORD BytesWritten;

    if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0)
    {
        printf("WaitNamedPipe failed with error %d\n",
            GetLastError());
        return;
    }

    // Create the named pipe file handle
    if ((PipeHandle = CreateFile(PIPE_NAME,
        GENERIC_READ | GENERIC_WRITE, 0,
        (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        (HANDLE) NULL)) == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile failed with error %d\n", GetLastError());
        return;
    }

    if (WriteFile(PipeHandle, "This is a test", 14, &BytesWritten, 
        NULL) == 0)
    {
        printf("WriteFile failed with error %d\n", GetLastError());
        CloseHandle(PipeHandle);
        return;
    }

    printf("Wrote %d bytes", BytesWritten);

    CloseHandle(PipeHandle);
}
于 2009-02-09T04:04:26.680 回答