用于服务的Windows命名管道无法正常工作

时间:2012-10-23 14:52:30

标签: visual-c++ service named-pipes

我使用windows命名管道示例。当我运行示例程序来创建管道时,写一些东西并在客户端程序中接收它一切都很好。当我将客户端代码移动到dll中时,它在Windows服务中运行它只是不会收到发送的字节。

服务器代码如下:

ThreadParams * params = reinterpret_cast<ThreadParams*>(args);
CString * connectionString = params->connectString;

HANDLE hPipe;
DWORD dwBytesRead;
TCHAR buf[1024];
int len;

hPipe = CreateNamedPipe(PIPE_NAME,  // Name
                        PIPE_ACCESS_OUTBOUND | WRITE_OWNER, // OpenMode
                        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // PipeMode
                        2, // MaxInstances
                        1024, // OutBufferSize
                        1024, // InBuffersize
                        2000, // TimeOut
                        NULL); // Security
if (hPipe == INVALID_HANDLE_VALUE)
{
    Globals::WriteLog("Could not create the pipe",1);
    exit(1);
}

Globals::WriteLog("connect...",1);
ConnectNamedPipe(hPipe, NULL);
Globals::WriteLog("...connected",1);

swprintf(buf, connectionString->GetBuffer());
len = wcslen(buf);

if (!WriteFile(hPipe, buf, len*sizeof(TCHAR), &dwBytesRead, NULL))
    Globals::WriteLog("WriteFile failed",1);
else
    wprintf(L"written %d bytes\n",dwBytesRead);

DisconnectNamedPipe(hPipe);

CloseHandle(hPipe);

客户:

    CString finalResult = _T("");

HANDLE      hOut = INVALID_HANDLE_VALUE;
TCHAR       buf[1024];
DWORD       len;
DWORD       dwWritten;

Global::WriteLog("pwrite: waiting for the pipe...",1);
if (WaitNamedPipe(PIPE_NAME, NMPWAIT_WAIT_FOREVER) == 0)
{
    Global::WriteLog("WaitNamedPipe failed. error=%d",1,GetLastError());
    goto cleanup;
}
Global::WriteLog("the pipe is ready",1);

hOut = CreateFile(PIPE_NAME,
    GENERIC_READ,
    0,
    NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
if (hOut == INVALID_HANDLE_VALUE)
{
    Global::WriteLog("CreateFile failed with error %d",1,GetLastError());
    goto cleanup;
}
Global::WriteLog("Opened the pipe",1);

for (;;)
{
    if (!ReadFile(hOut, buf, sizeof(buf), &dwWritten, NULL))
    {
        Global::WriteLog("ReadFile failed -- probably EOF. Read %d bytes.",1,dwWritten);
        goto cleanup;
    }
    else
        break;
}

finalResult = CString(buf);
Global::WriteLog("String from pipe:%S",1,buf);
cleanup:
if(hOut != INVALID_HANDLE_VALUE)
    CloseHandle(hOut);

服务器的代码在一个线程中运行,如果它改变任何东西(我在示例程序中使用此线程版本测试它并且没有问题)。

为什么不起作用?

提前致谢

1 个答案:

答案 0 :(得分:1)

好吧,我似乎已经明白了。我似乎没有正确理解文档。

在服务器端,WriteFile函数在读取字符串之前不会阻塞。我的程序只是编写数据然后关闭句柄 - 管道。客户端没有收到消息并抛出错误,指出管道的另一端没有进程。

同样来自客户端我删除了(;;)循环。

要等待客户端的读取操作完成,我添加了

FlushFileBuffers(hPipe);

成功写入操作后。

希望能帮助某人