Jkh*_*kh2 4 c# c++ windows ipc named-pipes
我正在尝试开始使用命名管道,因为我将来需要将它们用于我的项目。
目前我有一个 C++ 服务器,它会等待客户端连接并发送测试消息。我大致是按照这个教程开始的。相关代码如下:
#define MESSAGE L"TestMessage"
HANDLE hnamedPipe = INVALID_HANDLE_VALUE;
hnamedPipe = CreateNamedPipe(
L"\\\\.\\pipe\\testpipe",
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|
PIPE_READMODE_MESSAGE|
PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1024,
1024,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if(hnamedPipe == INVALID_HANDLE_VALUE)
{
cout << "Failed" << endl;
}
while(true)
{
cout<< "Waiting for client"<< endl;
if(!ConnectNamedPipe(hnamedPipe,NULL))
{
if(ERROR_PIPE_CONNECTED != GetLastError())
{
cout << "FAIL"<< endl;
}
}
cout<<"Connected!"<<endl;
//Send over the message
wchar_t chResponse[] = MESSAGE;
DWORD cbResponse,cbWritten;
cbResponse = sizeof(chResponse);
if(!WriteFile(
hnamedPipe,
chResponse,
cbResponse,
&cbWritten,
NULL))
{
wprintf(L"failiure w/err 0x%08lx\n",GetLastError);
}
cout<<"Sent bytes :)" << endl;
}
Run Code Online (Sandbox Code Playgroud)
客户端代码(C#)如下:
using (NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
{
while (true)
{
Console.WriteLine("Connecting to server...");
pipeClient.Connect();
Console.WriteLine("Connected :)");
Console.WriteLine(pipeClient.ReadByte());
pipeClient.Close();
Console.WriteLine("Closed");
}
}
Run Code Online (Sandbox Code Playgroud)
目前我已经让客户端成功连接到服务器并打印出第一个字节。我想知道如何做两件事:
阅读整个消息 - 我尝试在 pipelineClient 上使用 StreamReader 来读取消息,但它无限期地挂在 ReadLine() 上。
连续发送消息 - 我希望服务器将一条又一条消息发送到客户端,客户端将一次读取一条消息并将其打印出来。我对 IPC 有点一无所知,所以首先我尝试让客户端在 while(true) 循环中断开连接并重新连接到服务器,而服务器处于 while true 循环中,该循环在顶部总是等待新的客户端连接发送另一条消息。我的尝试在上面的代码中。
任何对此的帮助将不胜感激。最终的目标是将图像从服务器发送到客户端。然后,客户会将它们实时打印到屏幕上。在尝试图像数据之前,我想使用简单的字符串消息来实现此功能。
编辑:
最终,我希望能够从客户端向服务器发送一条消息,指示它想要获取最新的图像帧,然后服务器将发送最新的帧,然后客户端将其显示在屏幕上。所以流程是:
ReadLine挂起是因为它正在等待换行符,而您的测试消息不包含换行符。
如果您希望服务器连续发送消息,只需在调用中循环即可WriteFile。您无需连接多次。同样在客户端中,将循环放在ReadLine.
如果每条消息都包含以换行符结尾的文本,那么这就足够了,但是如果您确实希望管道客户端在消息模式下工作,您需要调用:
pipeClient.ReadMode = PipeTransmissionMode.Message;
Run Code Online (Sandbox Code Playgroud)
但是,我怀疑这是否能与StreamReader. 相反,您应该使用 来读取单个消息pipeClient.Read。
更新
回答你的新问题:
在服务器上,一旦客户端连接就进入一个循环,其中:
在客户端上,一旦连接到服务器,就会进入一个循环,其中:
我不会使用消息模式管道。如果帧的大小是固定的,那么客户端知道要从服务器读取多少数据。否则,在帧之前添加一个包含其长度的 uint。