C#中命名的管道输入输出

时间:2018-04-15 04:59:01

标签: c# named-pipes streamwriter

我正在使用命名管道,并且非常混淆客户端和服务器之间的交互是如何发生的。 我的服务器是一个附有命名管道的VM。我用C#创建了一个客户端流:

NamedPipeClientStream client = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut);

让我们说VM提示符如下:

Hello!
Do you accept (y/n): y
Text1 : 1.2.3.4
Text2 : 2.3.4.5

我基本上需要做的是,检查流读取的行是否为"您是否接受(y / n):",如果匹配,则将y写入{{1}使用Text1,然后在流

中写入1.2.3.4

我面临的问题:

  1. 提示在stream.es之后不显示任何内容。我的想法 是的,它可能正在等待下一个输入。所以,而不是做 这样:

    Hello!

    我这样做了:

    if(line.contains("Do you accept (y/n):"))
           writer.writeLine("y")
    
  2. 这是正确的吗?如果是,则表示服务器 不要在正在等待输入的缓冲区中推送文本。 所以,每次我必须检查前一行和 将下一个预期行的输出写入写入流?

  3. 另外,如上所述,为if(line.contains("Hello!")) writer.writeLine("y"); 传递1.2.3.4,我这样做了:

    Text1

    我的执行提示中显示的是:if(line.contains("Do you accept (y/n):")) writer.writeLine("1.2.3.4") 即。它' S 只重复我传递的输入的第一个字符。为什么 这样?我已将Text1 : 1111111设置为我的编写器流。

  4. 这里的任何指示都将受到高度赞赏!

    修改:包含代码段

    AutoFlush = true

    是正确的方式吗? 此外,有时管道读取器缺少数据。就像它显示Tet1而不是Text1。为什么这样?

1 个答案:

答案 0 :(得分:0)

您有此声明:while(!client.IsConnected);会导致客户端在继续之前等待连接。但是,客户端从不尝试连接(client.Connect();),因此可能您将永远等待。将该行替换为if (!client.IsConnected) {client.Connect();}以使其生效。

除此之外,根据评论,在不知道服务器端代码是什么样的情况下,很难说客户端应该发送什么内容;因为双方正在进行脚本对话。

以下是一些工作服务器的示例&客户端代码,说明如何执行此对话:

启动客户端和代码的代码服务器:

static void Main()
{
    var server = Task.Factory.StartNew(() => RunServer());
    var client = Task.Factory.StartNew(() => RunClient());
    Task.WaitAll(server, client);
    Console.WriteLine("Done");
}

客户代码:

static void RunClient()
{
    using (var pipeClient = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut))
    {
        Console.WriteLine("Client is waiting to connect");
        if(!pipeClient.IsConnected){pipeClient.Connect();}
        Console.WriteLine("Client is connected");
        using (var reader = new StreamReader(pipeClient))
        {
            using (var writer = new StreamWriter(pipeClient))
            {
                var running = true;
                while(running) 
                {
                    Console.WriteLine("Client is waiting for input");
                    var message = reader.ReadLine();
                    if (message != null)
                    {
                        Console.WriteLine("Client: Recieved from server {0}", message);
                        switch (message)
                        {
                            case "Do you accept (y/n):":
                                writer.WriteLine("y");
                                writer.WriteLine("quit");
                                writer.Flush();
                                break;
                            case "quit": 
                                running = false; 
                                break;
                        }
                    }
                } 
            }
        }
    }
    Console.WriteLine("Client Quits");
}

服务器代码:

static void RunServer()
{
    using (var pipeServer = new NamedPipeServerStream("TestPipe", PipeDirection.InOut))
    {
        using (var reader = new StreamReader(pipeServer))
        {
            using (var writer = new StreamWriter(pipeServer))
            {
                var running = true;
                Console.WriteLine("Server is waiting for a client");
                pipeServer.WaitForConnection();
                Console.WriteLine("Server has connection from client");
                Console.WriteLine("Server: Saying Hi");
                writer.WriteLine("Hello!");
                Console.WriteLine("Server: Prompting for Input");
                writer.WriteLine("Do you accept (y/n):");
                writer.Flush();
                while(running) 
                {
                    pipeServer.WaitForPipeDrain();
                    var message = reader.ReadLine();
                    Console.WriteLine("Server: Recieved from client {0}", message);
                    if (message.Equals("quit")) 
                    {
                        writer.WriteLine("quit");
                        running = false;
                    }
                } 
            }
        }
    }
    Console.WriteLine("Server Quits");
}

更新

修改了读取字符而不是行的代码;因此,在查看服务器的消息之前,我们不必等待换行符。

//using System.Threading.Tasks;
//using System.IO.Pipes;

static void Main()
{
    var server = Task.Factory.StartNew(() => RunServer());
    var client = Task.Factory.StartNew(() => RunClient());
    Task.WaitAll(server, client);
    Console.WriteLine("Done");
}

static void RunClient()
{
    using (var pipeClient = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut))
    {
        Console.WriteLine("Client is waiting to connect");
        if(!pipeClient.IsConnected){pipeClient.Connect();}
        Console.WriteLine("Client is connected");
        using (var reader = new StreamReader(pipeClient))
        {
            using (var writer = new StreamWriter(pipeClient))
            {
                var message = string.Empty;
                var running = true;
                while(running) 
                {
                    Console.WriteLine("Client is waiting for input");
                    var chr = reader.Read();
                    if (chr >= 32)
                    {
                        message = message + (char)chr;
                        Console.WriteLine("Client: Recieved from server {0}", message);
                        switch (message)
                        {
                            case "Do you accept (y/n):":
                                writer.WriteLine("y");
                                writer.WriteLine("quit");
                                writer.Flush();
                                break;
                            case "quit": 
                                running = false; 
                                break;
                        }
                    }
                    else {
                        message = string.Empty;
                        Console.WriteLine("Client: New Line Received from Server");
                    }
                } 
            }
        }
    }
    Console.WriteLine("Client Quits");
}

static void RunServer()
{
    using (var pipeServer = new NamedPipeServerStream("TestPipe", PipeDirection.InOut))
    {
        using (var reader = new StreamReader(pipeServer))
        {
            using (var writer = new StreamWriter(pipeServer))
            {
                var running = true;
                Console.WriteLine("Server is waiting for a client");
                pipeServer.WaitForConnection();
                Console.WriteLine("Server has connection from client");
                Console.WriteLine("Server: Saying Hi");
                writer.WriteLine("Hello!");
                Console.WriteLine("Server: Prompting for Input");
                writer.Write("Do you accept (y/n):"); //NB: This is a write, not a write line!
                writer.Flush();
                while(running) 
                {
                    pipeServer.WaitForPipeDrain();
                    var message = reader.ReadLine();
                    Console.WriteLine("Server: Recieved from client {0}", message);
                    switch (message)
                    {
                        case "quit":  
                            writer.WriteLine("quit");
                            running = false;
                            break;
                        default:
                            writer.WriteLine("");
                            break;
                    } 
                }
            }
        }
    }
    Console.WriteLine("Server Quits");
}

所以这就是你的代码应该是这样的:

int charAsInt;
var line = string.Empty;
while(((charAsInt = reader.Read()) != -1)) {
    if (charAsInt >= 32) { //is a displayable character
        line = line + (char)charAsInt;

        //your code to handle the lines
        if(line.Contains("Hello!")) {
            writer.WriteLine("1.2.3.4"); // input for the next prompt
        } else if(line.Contains("Text1") {
            writer.WriteLine("2.3.4.5"); // input for next prompt of Text2
        }
        writer.Flush();
        //writer.WaitForPipeDrain();

    } else { //is a control character
        if (charAsInt == 10 || charAsInt == 13) { //carriage return or line feed; i.e. end of line
            if (line.Length > 0) {
                Debug.WriteLine("Last line read was {0}", line); //just so you can see info as it comes from the server
                line = string.Empty;
            }
        }
    }
}