C++: Реализация Именованных каналов с помощью API Win32

Я пытаюсь реализовать именованные каналы в 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 (некоторые странные, что я изображаю).

Решение:

Читатель (Сервер):

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;

Блоки сервера, пока это не получает связанный клиент, чтения, что клиент пишет и затем собирается для нового соединения, до бесконечности. Спасибо за справку, все!

18
задан O. Jones 1 August 2013 в 23:46
поделиться

2 ответа

Вы должны использовать CreateNamedPipe() для создания серверного конца именованной трубы. Обязательно укажите ненулевой размер буфера, нулевой (документированный в MSDN как 'use system default buffer size') не работает. В MSDN есть достойные примеры для многопоточного клиента и сервера.

13
ответ дан 30 November 2019 в 08:26
поделиться

Клиент именованного канала может открыть именованный канал с помощью CreateFile , но сервер именованного канала должен использовать CreateNamedPipe , чтобы создать именованный канал. После создания именованного канала сервер использует ConnectNamedPipe для ожидания подключения клиента. Только после подключения клиента сервер должен выполнить чтение блокировки, как ваш вызов ReadFile .

13
ответ дан 30 November 2019 в 08:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: