0

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

服务器的代码如下:

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);

如果更改任何内容,服务器的代码将在线程中运行(我已经在示例程序中使用此线程版本对其进行了测试,并且没有问题)。

为什么它不起作用?

提前致谢

4

1 回答 1

1

好吧,看来我想通了。看来我没有正确理解文档。

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

同样从客户端我删除了 for(;;) 循环。

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

FlushFileBuffers(hPipe);

写入操作成功后。

希望对某人有所帮助

于 2012-10-24T15:50:03.733 回答