如何在C#中阻止命名管道?

时间:2016-07-28 01:38:38

标签: c# windows named-pipes

我正在编写一个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函数将句柄连接到另一个客户端。

2 个答案:

答案 0 :(得分:2)

客户端正在断开管道连接,因此服务器在收到测试消息后立即看到输入流的结束。

StreamReader.ReadLine()的文档说:

  

输入流的下一行,如果到达输入流的末尾,则为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());
}