Synchronizing reading and writing with synchronous NamedPipes

我与影子孤独终老i 提交于 2019-12-21 23:22:49

问题


A Named Pipe Server is created with

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

Then we immediately call:

ConnectNamedPipe( hPipe, BYVAL %NULL )

Which blocks until the client connects.

Then we proceed directly to ReadFile( hPipe, ...

The problem is that it takes the Client takes a finite amount of time to prepare and write all the fcgi request parameters. This has usually not completed before the Pipe Server performs its ReadFile(). The Read file operation thus finds no data in the pipe and the process fails.

Is there a mechanism to tell when a Write() has occurred/finished after a client has connected to a NamedPipe?

If I had control of the Client process, I could use a common Mutex, but I don't, and I really do not want to get into I/O completion ports just to solve this problem!

I can of course use a simple timer to wait 60m/s or so which is usually plenty of time for the write to complete, but that is a horrible hack.


回答1:


I'm not sure what language you're using - I don't recognize the expression like

PIPE_TYPE_BYTE OR %PIPE_WAIT OR %PIPE_READMODE_BYTE

but it looks like to me that the server's ReadFile() should block until data is written by the client.

One thing that doesn't look right (but shouldn't be hurting anything) is the use of NMPWAIT_USE_DEFAULT_WAIT - that value is intended for a client's use when calling WaitNamedPipe().

Could you see if these 2 C++ programs interact like you expect (ie., with the server blocking until the client writes something)? I took these programs from the Jones/Ohlund book "Network Programming for Windows" The server blocks in the ReadFile() call for me as expected:

- server.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);
}

- client.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);
}


来源:https://stackoverflow.com/questions/527012/synchronizing-reading-and-writing-with-synchronous-namedpipes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!