3.客户端代码 在实验一的基础上,客户端使用两个线程,一个线程中实例一个客户端,使用管道通信向客户端发送数据(数据结构转为string类型);另一个线程中接收服务器端管道中的数据,再将string转为定义的数据结构。
-
- PassStruct myPass = new PassStruct(
- new int[,]{
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9},
- {1,2,3,4,5,6,7,8,9}
- },
- new byte[16] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7 },
- "Authror:小魏");
- private void 打开aToolStripMenuItem_Click(object sender, EventArgs e)
- {
- A = new Thread(new ThreadStart(exePa));
- A.IsBackground = true;
- A.Start();
- }
-
-
- delegate void setRtbHandler(string s);
- private void setRtb(string s)
- {
- tabPage2.Controls[0].Text += s;
- }
-
-
-
-
- private void exePa()
- {
-
-
- info += "线程A(写入线程)打开\n";
- try{
-
- NamedPipeClientStream pipeClientA =
- new NamedPipeClientStream("WEI-THINKPAD", "testpipe",
- PipeDirection.InOut, PipeOptions.None,
- TokenImpersonationLevel.Impersonation);
- StreamWriter sw = new StreamWriter(pipeClientA);
- StreamReader sr = new StreamReader(pipeClientA);
- pipeClientA.Connect();
- sw.AutoFlush = true;
-
-
- if (sr.ReadLine() == "My Server!")
- {
-
- toWrite = StructToString(myPass);
- sw.Write(toWrite);
- }
- else
- {
- info +="Server could not be verified.\n";
- }
-
- pipeClientA.Close();
- }
- catch(Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
-
-
-
-
-
-
- private void 关闭AToolStripMenuItem_Click(object sender, EventArgs e)
- {
- if (A.IsAlive)
- {
- info += "线程A(写入线程)已关闭\n";
- A.Abort();
- }
- }
-
- private void 打开aToolStripMenuItem1_Click(object sender, EventArgs e)
- {
- B = new Thread(new ThreadStart(exePb));
- B.IsBackground = true;
- B.Start();
- }
-
-
-
-
- private void exePb()
- {
- info += "线程B(读出线程)打开\n";
- try
- {
- NamedPipeClientStream pipeClientB =
- new NamedPipeClientStream("WEI-THINKPAD", "testpipe",
- PipeDirection.InOut, PipeOptions.None,
- TokenImpersonationLevel.Impersonation);
- StreamWriter sw = new StreamWriter(pipeClientB);
- StreamReader sr = new StreamReader(pipeClientB);
- pipeClientB.Connect();
- sw.AutoFlush = true;
- if (sr.ReadLine() == "My Server!")
- {
-
- PassStruct getPass = StringToStruct(toWrite);
- string structToShow="";
-
-
- for (int i = 0; i < 9; i++)
- {
- for (int j = 0; j < 9; j++)
- {
- structToShow += getPass.arrayInt[i, j].ToString() + " ";
- }
- structToShow += "\n";
- }
- for (int k = 0; k < 16; k++)
- structToShow += getPass.arrayByte[k].ToString() + " ";
- structToShow += "\n";
- structToShow += getPass.ss;
- structToShow += "\n";
-
- info += structToShow;
- }
- else
- {
- info += "Server could not be verified.\n";
- }
- pipeClientB.Close();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
-
- }
-
-
-
-
-
-
- private void 关?闭à?ToolStripMenuItem1_Click(object sender, EventArgs e)
- {
- if (B.IsAlive)
- {
- B.Abort();
- A.Abort();
- info += "线程B(读出线程)已关闭\n";
- this.tabPage2.Controls[0].Text = info;
- }
- }
4.数据结构与string相互转化的函数 -
- public string StructToString(PassStruct ps)
- {
- string s = "";
- for (int i = 0; i < 9; i++)
- for (int j = 0; j < 9; j++)
- s =s+(ps.arrayInt[i, j]).ToString() + ",";
- for (int k = 0; k < 16; k++)
- s = s + (ps.arrayByte[k]).ToString() + ",";
- s = s + ps.ss;
- return s;
- }
-
-
- public PassStruct StringToStruct(string s)
- {
- int[,] x = new int[9, 9];
- for (int i = 0; i < 9; i++)
- {
- for (int j = 0; j < 9; j++)
- {
- int p = s.IndexOf(',');
- string tmp = s.Substring(0, p);
- x[i, j] = int.Parse(tmp);
- s = s.Remove(0, p + 1);
- }
- }
-
- byte[] y = new byte[16];
- for (int k = 0; k < 16; k++)
- {
- int p = s.IndexOf(',');
- string tmp = s.Substring(0, p);
- y[k] = byte.Parse(tmp);
- s = s.Remove(0, p + 1);
- }
-
- PassStruct getPass = new PassStruct(x, y, s);
- return getPass;
- }
5.实验中遇到的问题 实验的大部分地方都是用try catch来处理异常,catch中通过MessageBox显示可以很快看到错误问题。实验中遇到: ![](http://image52.360doc.com/DownloadImg/2012/06/2021/24990865_1.gif)
网上查阅了一些资料,了解信号灯也是进程间通信的一种方式。“信号灯与其它进程间通信方式有所不同,它主要用于进程间同步。通常所说的系统V信号灯实际上是一个信号灯的集合,可用于多种共享资源的进程间同步。每个信号灯都有一个值,可以用来表示当前该信号灯代表的共享资源可用(available)数量,如果一个进程要申请共享资源,那么就从信号灯值中减去要申请的数目,如果当前没有足够的可用资源,进程可以睡眠等待,也可以立即返回。”(http://www.cnblogs.com/thinkingworld/articles/1861739.html) 不少人遇到过这个故障(数据库中或硬盘读盘),但最终还是没有读懂,不知道自己为什么会遇到这个问题。猜测可能还是不同线程向窗口写入东西(改变空间属性)引起的问题。于是将输出的信息改为一次性输出,暂时没有再出现问题。(具体见代码中注释) 实验结果:服务器端输出截图: ![](http://image52.360doc.com/DownloadImg/2012/06/2021/24990865_2.gif) 客户端截图: ![](http://image52.360doc.com/DownloadImg/2012/06/2021/24990865_3.gif)
|