我正在尝试开始使用命名管道,因为我将来需要将它们用于我的项目。
目前我有一个C ++服务器,它等待客户端连接并通过测试消息发送。我粗略地跟着这个tutorial开始了。相关代码如下:
#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;
}
客户端代码(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");
}
}
目前我已经让客户端成功连接到服务器并打印出第一个字节。我想知道如何做两件事:
阅读整个消息 - 我尝试在pipeClient上使用StreamReader来读取消息,但它无限期地挂在ReadLine()上。
持续发送消息 - 我希望服务器在消息发送到客户端后发送消息,客户端将一次读取消息并将其打印出来。我对IPC有点无能为力,所以一开始我尝试让客户端断开连接并在while(true)循环中重新连接到服务器,而服务器处于一个真正的循环中,在顶部总是等待新的客户端连接之前发送另一条消息。我的尝试是在上面的代码中。
对此的任何帮助将不胜感激。最终目标是将图像从服务器发送到客户端。然后客户端将它们实时打印到屏幕上。在尝试使用图像数据之前,我希望能够使用简单的字符串消息。
编辑:
最终我希望能够从客户端向服务器发送消息,表明它想要获取最新的图像帧,然后服务器将发送最新的帧,然后客户端将在屏幕上显示。所以流程是:
答案 0 :(得分:4)
ReadLine
挂起,因为它正在等待换行符,而测试消息不包含换行符。
如果您希望服务器连续发送消息,只需在WriteFile
呼叫周围循环。您不需要连接多次。同样在客户端中,将循环放在ReadLine
。
如果每条消息都包含由换行符终止的文本,那么这应该足够了,但如果您真的希望管道客户端在消息模式下工作,则需要调用:
pipeClient.ReadMode = PipeTransmissionMode.Message;
但是,我怀疑这会与StreamReader
很好地互动。相反,您应该使用pipeClient.Read
阅读单个邮件。
<强>更新强>
回答你的新问题:
在服务器上,一旦客户端连接进入一个循环,其中:
在客户端上,一旦连接到服务器,输入一个循环:
我不会使用消息模式管道。如果帧的大小是固定的,则客户端知道从服务器读取多少数据。否则,在帧的前面加上一个包含其长度的uint。