我正在使用命名管道,并且非常混淆客户端和服务器之间的交互是如何发生的。 我的服务器是一个附有命名管道的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我面临的问题:
提示在stream.es
之后不显示任何内容。我的想法
是的,它可能正在等待下一个输入。所以,而不是做
这样:
Hello!
我这样做了:
if(line.contains("Do you accept (y/n):"))
writer.writeLine("y")
这是正确的吗?如果是,则表示服务器 不要在正在等待输入的缓冲区中推送文本。 所以,每次我必须检查前一行和 将下一个预期行的输出写入写入流?
另外,如上所述,为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
设置为我的编写器流。
这里的任何指示都将受到高度赞赏!
修改:包含代码段
AutoFlush = true
是正确的方式吗? 此外,有时管道读取器缺少数据。就像它显示Tet1而不是Text1。为什么这样?
答案 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;
}
}
}
}