服务器代码:
using (NamedPipeServerStream ns = new NamedPipeServerStream("simple", PipeDirection.InOut,1))
{
Console.WriteLine(">> 服务器等待连接..");
ns.WaitForConnection();
Console.WriteLine(">> 服务器连接成功。");
string msg = "1:服务器信息";
byte[] data = Encoding.Default.GetBytes(msg);
ns.Write(data, 0, data.Length);
ns.Flush();
ns.WaitForPipeDrain();
Queue<byte> returnData = new Queue<byte>();
int item;
while ((item = ns.ReadByte()) != -1)
{
returnData.Enqueue((byte)item);
}
data = returnData.ToArray();
msg = Encoding.Default.GetString(data);
Console.WriteLine(">> 客户端发送的信息" + msg);
}
Console.WriteLine(">> 服务器结束,按回车键关闭窗口");
Console.ReadLine();
客户端代码:
using (NamedPipeClientStream nc = new NamedPipeClientStream(".", "simple", PipeDirection.InOut))
{
Console.WriteLine(">> 客户端等待连接");
nc.Connect();
Console.WriteLine(">> 客户端连接成功");
string msg = "";
Queue<byte> returnData = new Queue<byte>();
int item;
while ((item = nc.ReadByte()) != -1)
{
returnData.Enqueue((byte)item);
}
byte[] data = returnData.ToArray();
msg = Encoding.Default.GetString(data);
Console.WriteLine(">> 服务器发送的信息:{0}", msg);
msg = "1:客户端的信息";
Console.WriteLine(">> 向服务器发送信息:" + msg);
data = Encoding.Default.GetBytes(msg);
nc.Write(data, 0, data.Length);
nc.Flush();
nc.WaitForPipeDrain();
}
Console.WriteLine(">> 客户端结束,按回车键关闭窗口");
Console.ReadLine();
目前对此问题的发现是
1:双向的管道似乎不太适合使用StreamReader和StreamWriter来读写。因为当需要关闭StreamReader和StreamWriter时,后关闭的那个会因为管道已关闭而导致Close方法异常。
2:当服务器写输入,客户端读数据,没有其他读写操作时,且服务器不使用RunAsClient时,通信正常。当服务器有一次对客户端的写和对客户端的读,客户端对应的一次对服务器的读,一次对服务器的写实,服务器的读的位置与客户端的读的位置都会卡住进程,强制关闭服务器,客户端的读会继续,但,当然之后的写会因为管道的关闭而引发异常。
问题是:为什么会在服务器和客户端的读的位置卡住?
两头堵住的原因是因为,没有可读的数据,使用NamedPipeClientStream或NamedPipeServerStream的Read读取是,并不会以返回-1值的形式报告数据已读完,当数据读完后,Read会堵塞,而不是返回-1,当客户端堵塞,服务器也会因为读取没有的数据而进入等待,从而导致堵塞。
写错了,应该是“..使用NamedPipeClientStream或NamedPipeServerStream的ReadByte读取...”
等待数据返回
可我服务器已经向管道写入数据了,为什么会卡主?应该能够读出来才对。
@北在北方: writer.Write(noteMsg) 后面加一句 writer.Flush()
@Launcher: Flush也不起作用,我修改了代码,请再瞧瞧。
@北在北方: 客户端阻塞在 string strData = reader.ReadLine() 这一句时,服务端阻塞在哪一句上?
@Launcher: 服务器一段堵在了string response = reader.ReadLine();这行,当我关闭服务器时,客户端读取到服务器首次发送的信息,然后报出管道已关闭的异常。为什么客户端会堵在ReadLine?服务器我都Flush了也没用吗,应该怎么做。
@北在北方: writer.WriteLine(noteMsg); // 对应客户端 string strData = reader.ReadLine()
writer.Flush();
@Launcher: 修改了问题,请再看看。
因为你写入的不是一行数据。
行结束符\r\n是很重要的。