Подтвердить что ты не робот

С++: реализация именных каналов с использованием API Win32

Я пытаюсь реализовать именованные каналы на С++, но либо мой читатель ничего не читает, либо мой писатель ничего не пишет (или и то, и другое). Здесь мой читатель:

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;

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

4b9b3361

Ответ 1

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

Ответ 2

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