本文介绍了C ++:使用Win32 API实现命名管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在C ++中实现命名管道,但要么我的读者什么都没读,或者我的作家什么都不写(或两者都不写).这是我的读者:

int main()
{
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

    char data[1024];
    DWORD numRead = 1;

    while (numRead >= 0)
    {
        ReadFile(pipe, data, 1024, &numRead, NULL);

        if (numRead > 0)
            cout << data;
    }

    return 0;
}

LPCWSTR GetPipeName()
{
    return L"\\\\.\\pipe\\LogPipe";
}

这是我的作家:

int main()
{
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

    string message = "Hi";
    WriteFile(pipe, message.c_str(), message.length() + 1, NULL, NULL);

    return 0;
}

LPCWSTR GetPipeName()
{
    return L"\\\\.\\pipe\\LogPipe";
}

看起来不错吗?出于某种原因,阅读器中的numRead始终为0,并且仅读取1024 -54(有些奇怪的I字符).

解决方案:

阅读器(服务器):

while (true)
{
    HANDLE pipe = CreateNamedPipe(GetPipeName(), PIPE_ACCESS_INBOUND | PIPE_ACCESS_OUTBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);

    if (pipe == INVALID_HANDLE_VALUE)
    {
        cout << "Error: " << GetLastError();
    }

    char data[1024];
    DWORD numRead;

    ConnectNamedPipe(pipe, NULL);

    ReadFile(pipe, data, 1024, &numRead, NULL);

    if (numRead > 0)
        cout << data << endl;

    CloseHandle(pipe);
}

作家(客户):

HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if (pipe == INVALID_HANDLE_VALUE)
{
    cout << "Error: " << GetLastError();
}

string message = "Hi";

cout << message.length();

DWORD numWritten;
WriteFile(pipe, message.c_str(), message.length(), &numWritten, NULL);

return 0;

服务器阻塞,直到它获得一个已连接的客户端,读取该客户端编写的内容,然后自行设置以建立新的连接,这是无限的.谢谢大家的帮助!

解决方案

您必须使用 CreateNamedPipe() 创建命名管道的服务器端.确保指定非零缓冲区大小,零(MSDN记录为使用系统默认缓冲区大小")不起作用. MSDN具有用于多线程客户端和服务器的不错的示例. >

I'm trying to implement named pipes in C++, but either my reader isn't reading anything, or my writer isn't writing anything (or both). Here's my reader:

int main()
{
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

    char data[1024];
    DWORD numRead = 1;

    while (numRead >= 0)
    {
        ReadFile(pipe, data, 1024, &numRead, NULL);

        if (numRead > 0)
            cout << data;
    }

    return 0;
}

LPCWSTR GetPipeName()
{
    return L"\\\\.\\pipe\\LogPipe";
}

And here's my writer:

int main()
{
    HANDLE pipe = CreateFile(GetPipeName(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

    string message = "Hi";
    WriteFile(pipe, message.c_str(), message.length() + 1, NULL, NULL);

    return 0;
}

LPCWSTR GetPipeName()
{
    return L"\\\\.\\pipe\\LogPipe";
}

Does that look right? numRead in the reader is always 0, for some reason, and it reads nothing but 1024 -54's (some weird I character).

Solution:

Reader (Server):

while (true)
{
    HANDLE pipe = CreateNamedPipe(GetPipeName(), PIPE_ACCESS_INBOUND | PIPE_ACCESS_OUTBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);

    if (pipe == INVALID_HANDLE_VALUE)
    {
        cout << "Error: " << GetLastError();
    }

    char data[1024];
    DWORD numRead;

    ConnectNamedPipe(pipe, NULL);

    ReadFile(pipe, data, 1024, &numRead, NULL);

    if (numRead > 0)
        cout << data << endl;

    CloseHandle(pipe);
}

Writer (client):

HANDLE pipe = CreateFile(GetPipeName(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if (pipe == INVALID_HANDLE_VALUE)
{
    cout << "Error: " << GetLastError();
}

string message = "Hi";

cout << message.length();

DWORD numWritten;
WriteFile(pipe, message.c_str(), message.length(), &numWritten, NULL);

return 0;

The server blocks until it gets a connected client, reads what the client writes, and then sets itself up for a new connection, ad infinitum. Thanks for the help, all!

解决方案

You must use CreateNamedPipe() to create the server end of a named pipe. Be sure to specify a non-zero buffer size, zero (documented by MSDN as 'use system default buffer size') doesn't work. MSDN has decent samples for a multi-threaded client&server.

这篇关于C ++:使用Win32 API实现命名管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 09:38
查看更多