Я пытаюсь реализовать именованные каналы в 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;
Блоки сервера, пока это не получает связанный клиент, чтения, что клиент пишет и затем собирается для нового соединения, до бесконечности. Спасибо за справку, все!
Вы должны использовать CreateNamedPipe()
для создания серверного конца именованной трубы. Обязательно укажите ненулевой размер буфера, нулевой (документированный в MSDN как 'use system default buffer size') не работает. В MSDN есть достойные примеры для многопоточного клиента и сервера.
Клиент именованного канала может открыть именованный канал с помощью CreateFile
, но сервер именованного канала должен использовать CreateNamedPipe
, чтобы создать именованный канал. После создания именованного канала сервер использует ConnectNamedPipe
для ожидания подключения клиента. Только после подключения клиента сервер должен выполнить чтение блокировки, как ваш вызов ReadFile
.