我正在尝试用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(我的角色有些奇怪)。
解决方案:
Reader(服务器):
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;
服务器阻塞,直到它获得连接的客户端,读取客户端写入的内容,然后无限制地为自己设置新连接。谢谢你的帮助,全部!
答案 0 :(得分:13)
您必须使用CreateNamedPipe()
来创建命名管道的服务器端。请务必指定非零缓冲区大小,零(由MSDN记录为“使用系统默认缓冲区大小”)不起作用。对于多线程客户端和服务器,MSDN有decent samples。
答案 1 :(得分:12)
命名管道客户端可以使用CreateFile
打开命名管道 - 但命名管道服务器需要使用CreateNamedPipe
来创建命名管道。在创建命名管道后,服务器使用ConnectNamedPipe
等待客户端连接。只有在客户端连接后,服务器才会执行阻止读取操作,就像调用ReadFile
一样。