我正在编写一个C#Windows服务(服务器),需要使用命名管道从C ++ GUI应用程序(客户端)接收消息很少见;在收到消息之前可能需要几天到几周。在我的测试中,我注意到它不是阻止数据进入,而是不断检查和打印换行符。它确实收到了测试消息,但我必须使用Visual Studio中的调试器进行验证。
有没有办法让C#部分阻止,直到实际收到数据?
- C#代码:
var client = new NamedPipeServerStream("PipeTest");
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
while (true)
{
Console.WriteLine(reader.ReadLine());
}
- C ++代码:
DWORD written;
INT error_code;
CHAR buffer[1024];
LPCWSTR pipe_name = L"\\\\.\\pipe\\PipeTest";
LRESULT result;
WaitNamedPipe(pipe_name, NMPWAIT_WAIT_FOREVER);
HANDLE hpipe = CreateFile(pipe_name,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
error_code = GetLastError();
sprintf_s(buffer,"Sending Test Message");
WriteFile(hpipe,buffer,strlen(buffer),&written,NULL);
result = GetLastError();
fprintf(stdout,"Pipe: %d Write: %d Written: %d",error_code,result,written);
DisconnectNamedPipe(hpipe);
CloseHandle(hpipe);
std::cin.get();
[ANSWER]
- 带有更正名称的C#代码( 服务器 ):
var server = new NamedPipeServerStream("PipeTest");
while (true)
{
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
Console.WriteLine(reader.ReadLine());
server.Disconnect();
}
对于此代码,我只需要捕获一行数据,@ The Shooter是正确的,但您需要添加server.Disconnect()
才能再次阅读。我从C documentation中找到了这个,并且相同的原理显然适用于C#。
服务器进程必须调用
DisconnectNamedPipe
才能将句柄与其先前的客户端断开连接,然后才能使用ConnectNamedPipe
函数将句柄连接到另一个客户端。
答案 0 :(得分:2)
客户端正在断开管道连接,因此服务器在收到测试消息后立即看到输入流的结束。
输入流的下一行,如果到达输入流的末尾,则为null。
所以ReadLine
正在返回null
;在这种情况下Console.WriteLine(String)做了什么?
如果value为null,则只将行终止符写入标准输出流。
QED。您所看到的行为完全符合预期。
您需要检查ReadLine
返回的值并正确处理null
。在这种情况下,你可能想等待另一个连接。
答案 1 :(得分:1)
而不是:
var client = new NamedPipeServerStream("PipeTest");
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
while (true)
{
Console.WriteLine(reader.ReadLine());
}
试试这个:
var client = new NamedPipeServerStream("PipeTest");
while (true)
{
client.WaitForConnection();
StreamReader reader = new StreamReader(client);
Console.WriteLine(reader.ReadLine());
}