有一个简单的命名管道服务器:
static void Main(string[] args)
{
StartServer();
Console.Read();
}
static void StartServer()
{
Task.Factory.StartNew(() =>
{
var server = new NamedPipeServerStream("TestPipes");
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
while (true)
{
var line = reader.ReadLine();
if (line == "Y")
{
for (int i = 0; i < 5; i++)
writer.WriteLine(i.ToString());
writer.Flush();
}
if (line=="N")
{
for (int i = 10; i < 15; i++)
writer.WriteLine(i.ToString());
writer.Flush();
}
}
});
}
非常简单的客户:
static void Main(string[] args)
{
//Client
var client = new NamedPipeClientStream(Environment.MachineName, "TestPipes");
client.Connect();
Console.WriteLine($"Connection esteblished at {DateTime.Now}, you may continue");
StreamReader reader = new StreamReader(client);
StreamWriter writer = new StreamWriter(client);
while (true)
{
string input = Console.ReadLine();
if (String.IsNullOrEmpty(input)) continue;
writer.WriteLine(input);
writer.Flush();
string serverString;
while (reader.Peek() >= 0)
{
serverString = reader.ReadLine();
Console.WriteLine(serverString);
}
}
}
但由于某种原因,只有第一个命令正在完成。 例如,如果我输入&#39; Y&#39;得到输出&#39; Y&#39;然后当N&#39; N&#39; N&#39; N&#39;输入什么都没有来自服务器。 需要让它连续工作。 谢谢。
答案 0 :(得分:1)
那是因为在您的客户端中您在while循环之外定义StreamReader reader = new StreamReader(client);
,所以在读者点击最后一行的第一次迭代中,底层流永远不会被重置,所以reader.Peek() >= 0
对后续调用产生错误。
在while循环中移动客户端阅读器对象的声明:
var client = new NamedPipeClientStream(Environment.MachineName, "TestPipes");
client.Connect();
Console.WriteLine($"Connection esteblished at {DateTime.Now}, you may continue");
StreamWriter writer = new StreamWriter(client);
while (true)
{
StreamReader reader = new StreamReader(client);
string input = Console.ReadLine();
if (String.IsNullOrEmpty(input)) continue;
writer.WriteLine(input);
writer.Flush();
string serverString;
while (reader.Peek() >= 0)
{
serverString = reader.ReadLine();
Console.WriteLine(serverString);
}
}
答案 1 :(得分:0)
使用Peek
很少有好主意,而且这也不是一个好主意。例如,尝试模拟服务器延迟,如下所示:
var line = reader.ReadLine();
if (line == "Y") {
for (int i = 0; i < 5; i++) {
writer.WriteLine(i.ToString());
writer.Flush();
// delay
Thread.Sleep(100);
}
}
你会看到你的代码Peek
(包括已接受的答案)将失败,只读一行(在后续输入中,如#34; N&#34;,将再次显示任何内容,只是像现在一样)。因此,使用Peek
的代码不可靠,并且会在最不合适的时刻出现意外失败。
相反,让服务器明确标记它发送的数据的结尾。例如,空行:
if (line == "Y") {
for (int i = 0; i < 5; i++) {
writer.WriteLine(i.ToString());
writer.Flush();
// simulate delay
Thread.Sleep(100);
}
// empty line
writer.WriteLine();
writer.Flush();
}
在客户端:
string serverString;
while (true)
{
serverString = reader.ReadLine();
if (!String.IsNullOrWhiteSpace(serverString))
Console.WriteLine(serverString);
else break;
};
此代码可靠地运行
将StreamReader
移动到内部while循环,因为其他答案建议也不需要,它看起来像是&#34;修复&#34;你的代码,但实际上它并没有解决任何问题,只是将你的问题置于地毯之下。