C#管道通讯
想请教下C#自带的管道通讯命名空间:using System.IO.Pipes;它其中包含两个客户端和服务端两个类:
做了个小测试,新建了连个项目,一个作为服务端,一个作为客户端,如下,是将各自的textBox中的值传到对方listBox并显示:
现在的问题是这样的:管道连接之后,单单从服务端(客户端)向客户端(服务端)发消息是可以的;如果先从服务端向客户端发送,再让客户端向服务端发送,则会卡死在客户端的Write过程(或如果先从客户端向服务端发送,再让服务端向客户端发送,则会卡死在服务端的Write过程),我的做法是停止当前管道连接,再重新新建一个管道连接才能发(有点扯蛋)……
对于MSDN中说的客户端和服务端之间支持异步操作,我不是太理解,是不是说仅仅需要连接一次,彼此都可以进行读写而不要重新关闭管道,再连上?我在网上搜了很多例子都是单向发的……重关管道再连,貌似是个不太好的方式。
如果大家知道管道仅连接一次,以后就可以实现互相收发,还请贴下代码……
服务端主要代码是:
//服务端向客户端发送 private void button1_Click(object sender, EventArgs e) { Thread SendData=new Thread(new ThreadStart(WriteData)); SendData.Start(); } private void WriteData() { try { this.listBox1.Items.Add("开始连接管道……"); pipeServer =new NamedPipeServerStream("testpipe", PipeDirection.InOut, 2); pipeServer.WaitForConnection(); Thread.Sleep(1000); if (pipeServer.IsConnected) { this.listBox1.Items.Add("与客户端连接成功^_^"); StreamWriter sw = new StreamWriter(pipeServer); sw.WriteLine(this.textBox1.Text); sw.Flush(); Thread.Sleep(1000); sw.Close(); } else { this.listBox1.Items.Add("与客户端连接失败(⊙_⊙)"); } } catch (Exception error) { this.listBox1.Items.Add(error.Message + "写数据时发生错误!"); } } //服务端从客户端接收数据 private void button2_Click(object sender, EventArgs e) { ReceiveDataThread = new Thread(new ThreadStart(ReceiveDataFromClient)); ReceiveDataThread.Start(); } private void ReceiveDataFromClient() { while (true) { try { pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 2); pipeServer.WaitForConnection();//等待 StreamReader sr = new StreamReader(pipeServer); string recData = sr.ReadLine(); this.listBox1.Items.Add(recData); Thread.Sleep(1000); sr.Close(); } catch (Exception) { throw; } if (tag==1) { break; } } }
//客户端向服务端发数据 private void button1_Click(object sender, EventArgs e) { Thread WriteData = new Thread(new ThreadStart(SendData)); WriteData.Start(); } private void SendData() { try { pipeClientA = new NamedPipeClientStream(@"\\.", "testpipe",PipeDirection.InOut, PipeOptions.None,TokenImpersonationLevel.Impersonation); pipeClientA.Connect(); StreamWriter sw = new StreamWriter(pipeClientA); sw.WriteLine(this.textBox1.Text); sw.Flush(); Thread.Sleep(1000); sw.Close(); } catch (Exception) { throw; } } //客户端从服务端接收数据 private void button4_Click(object sender, EventArgs e) { ReceiveData = new Thread(new ThreadStart(new MyDelegate(ReceiveDataFromServerAllways))); ReceiveData.Start(); } private void ReceiveDataFromServerAllways() { while (true) { Application.DoEvents(); if (tag == 1) { tag = 0; break; } try { pipeClientA = new NamedPipeClientStream(@"\\.", "testpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation); pipeClientA.Connect();//等待? if (pipeClientA.IsConnected) { this.listBox1.Items.Add("成功与服务器连接^_^"); Thread.Sleep(2000); StreamReader sr = new StreamReader(pipeClientA); string recData = sr.ReadLine(); if (recData != null) { this.listBox1.Items.Add(recData); } sr.Close(); } } catch (Exception error) { this.listBox1.Items.Add(error.Message + "读取数据过程出错!"); } } }