关于多线程的概念大家在编写程序的时候会经常的碰到。下边我就用一个多点通讯的例子来说明一下如何使用线程。

 

首先介绍服务器的代码主界面代码:

private void Form1_Load(object sender, EventArgs e)

         {

              BackServer lt = new BackServer();

         }

 

下面是  ReceThread类的代码

 

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

using System.IO;

using System.Net.Sockets;

 

namespace 多点通讯服务器

{

     class ReceThread

     {

         private BackServer service;

         System.Net.Sockets.TcpClient tcpclient = new TcpClient();//为每一个client生成一个TcpClient

         System.Threading.Thread thread;

         ThreadList threadlist=new ThreadList();

         System.IO.BinaryWriter bw;

 

         public ReceThread(BackServer backserver, System.Net.Sockets.TcpClient tcpclient)

         {

              this.service = backserver;

              this.tcpclient = tcpclient;//把特定的连接着记录下来

              thread = new Thread(this.StartForOne);//

        

              thread.Start();//开启线程

 

 

         }

         public void StartForOne()

         {

              string namelist="";

              while (true)

              {

 

 

                   bw = new BinaryWriter(tcpclient.GetStream());//生成一个属于该对象的读写器,而且在指定连接的tcpclient.GetStream流中读取

                   System.IO.BinaryReader br = new BinaryReader(tcpclient.GetStream());//生成一个读写器在数据流中写入数据

                       string LoginName=br.ReadString();//从流中读取登陆信息;

                       string login=LoginName.Substring(0,5);

                       //System.Windows.Forms.MessageBox.Show("login");

                       System.Threading.Thread.Sleep(2000);

                       if (login == "login")

                       {

 

                            threadlist.AddClientName(LoginName.Substring(5));//把登陆着姓名记录下来

                            for (int i = 0; i < threadlist.Count; i++)

                            {

                                 namelist += ((string)threadlist[i]) + ',';

                            }

 

                            for (int i = 0; i < threadlist.Count; i++)

                            {

                                 ReceThread send = (ReceThread)threadlist.GetThead(i);

                                 System.Threading.Thread.Sleep(2000);

                                 //System.Windows.Forms.MessageBox.Show("send");

                                 send.Sendinfomation(namelist);//向客户端发送在线人员列表

                                

                            }

                       }

                       else

                       {

                            string To = br.ReadString();//向谁说

                            string cmd = br.ReadString();//说什么

                            this.SendComtentforClient(To, cmd);//B

                       }

              }

 

              int j = this.threadlist.GetIndexByThread(this);

              this.threadlist.Remove(j);

              this.Abort();

 

         }

         private void Abort()

         {

              string manList = null;

              for (int i = 0; i < threadlist.Count; i++)//向客户端发送在线名单

              {

                   manList += (string)threadlist[i] + ",";

              }

              //   manList=(string)clients[clients.Count-1];

 

              for (int f = 0; f < threadlist.Count; f++)

              {

                   ReceThread w = (ReceThread)threadlist.GetThead(f);

                   w.Sendinfomation(manList);

 

 

              }

              this.tcpclient.Close();

              this.thread.Abort();

 

         }

         public void Sendinfomation(string content)

         {

 

              bw.Write(content);//写入流;

 

         }

         public void SendComtentforClient(string client, string content)//通过姓名得到相应的线程

         {

              int threadindex=threadlist.GetIndexClient(client);

              if (threadindex < 0)

              {

                   System.Windows.Forms.MessageBox.Show("No the client");

                   return;

              }

              ReceThread r = (ReceThread)threadlist.GetThead(threadindex);//通过id找到对应的实例

         //   r.Sendinfomation(content);//用对象的Sendinfomation方法

              r.bw.Write(content);//用该对象的读写器来写入流;

         }

     }

}

 

下边是BackServer类的代码:

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Net;

using System.Net.Sockets;

 

 

namespace 多点通讯服务器

{

     class BackServer

     {

         System.Net.Sockets.TcpListener tcplistener;

         System.Threading.Thread thread;

         ThreadList list=new ThreadList();

 

         public BackServer()

         {

              tcplistener = new TcpListener(1000);//1000端口监听

              thread = new System.Threading.Thread(this.Start);

              thread.Start();

          

         }

         public void Start()

         {

              while (true)//不停的监听每一为登陆者将得到一个线程

              {

                   tcplistener.Start();//监听开始了

                   //while (true)

                  //{

                       TcpClient tcpclient = tcplistener.AcceptTcpClient();//要等到有连接后才会执行下边的语句

                       ReceThread recethread = new ReceThread(this, tcpclient);//为每一个连接者开启一个线程tcpclient参数的目的是标记到底是谁的连接

                       list.AddThread(recethread);//把拥有该线程的对象加入数组

                   //}

              }

 

             

             

         }

     }

}

下边是ThreadList类的代码:

using System;

using System.Collections.Generic;

using System.Text;

using System.Collections;

 

namespace 多点通讯服务器

{

     class ThreadList

     {

         public static ArrayList Thread=new ArrayList();//存线程

         public static ArrayList Client = new ArrayList();//存登陆人员的名字

         public object GetThead(int i)//通过一个id号得到相应的线程

         {

              return Thread[i];

         }

         public object GetClient(int i)//通过id号得到相应的客户名称

         {

              return Client[i];

         }

 

         public object this[int index]//建立一个索引

         {

              get

              {

                   return Client[index];

              }

              set

              {

                   Client.RemoveAt(index);

                   Client.Insert(index, value);

              }

         }

         public int Count//

         {

              get

              {

                   return Thread.Count;

              }

         }

         public int GetIndexByThread(object SpecThread)//通过特定的线程来得到它的id

         {

              return Thread.IndexOf(SpecThread);

         }

         public int  GetIndexClient(string name)//通过名称得到nameid;

         {

              return Client.IndexOf(name);

         }

         public void AddClientName(object name)

         {

              Client.Add(name);//记住登陆人的名字

         }

 

         public void AddThread(object thread)

         {

              Thread.Add(thread);//加入线程

         }

 

         public void Remove(int i)

         {

              Client.RemoveAt(i);

              Thread.RemoveAt(i);

         }

     }

}

 

 

接下来是客户端的代码首先是登陆界面的代码:

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace 客户端

{

     public partial class Form1 : Form

     {

         public static System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();

         public static string fromname;

         public Form1()

         {

              InitializeComponent();

         }

 

         private void button1_Click(object sender, EventArgs e)

         {

              client.Connect("192.168.0.207", 1000);//登陆时就连接

              System.IO.BinaryWriter bw = new System.IO.BinaryWriter(client.GetStream());

              fromname = this.textBox1.Text;

              bw.Write("login" + fromname);

              Form2 form2 = new Form2();

              form2.Show();

         }

     }

}

 

下面是Form2 类的代码

 

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Net.Sockets;

using System.IO;

using System.Threading;

 

namespace 客户端

{

     public partial class Form2 : Form

     {

 

        private delegate void UpdateList2();

//由于新开启的线程无法控制主线程的控件所以这里要用到一个委托

private UpdateList2 myUpdateList2;

         private delegate void Updatetext1(string t);

         Updatetext1 myUpdatetext1;

         private TcpListener listener;

         private Thread t;

         public static string[] temps;

         public BinaryReader br = new BinaryReader(Form1.client.GetStream());

         public Form2()

         {

              InitializeComponent();

              t = new System.Threading.Thread(Start);

              t.Start();

         }

 

         private void button1_Click_1(object sender, EventArgs e)

         {

             

              string To = this.comboBox1.Text;

              string from = Form1.fromname;//登陆名

              //byte[] buffer =Encoding.UTF8.GetBytes(this.textBox2.Text);

              string s = this.textBox1.Text;

BinaryWriter bw = new BinaryWriter(Form1.client.GetStream());

              bw.Write(from);//谁说的

              bw.Write(To);//向谁说

              bw.Write("Talk" + s);//说什么

         }

         private void UpdateListMethod2()

         {

              for (int j = 0; j < temps.Length; j++)

              {

                   this.comboBox1.Items.Clear();

                   this.comboBox1.Items.Add(temps[j]);

}

         }

         private void UpdatetextMethod1(string content)

         {

              this.textBox2.Text += content;

         }

         private void Form2_Load(object sender, EventArgs e)

         {

 

         }

         public void Start()

         {

              myUpdateList2 = new UpdateList2(this.UpdateListMethod2);

              myUpdatetext1=new Updatetext1(this.UpdatetextMethod1);

              try

              {

                   while (true)

                   {

string manList = br.ReadString();//传过一个流来读成字符传区分是对话还是登陆

                       //System.Windows.Forms.MessageBox.Show("rec ");

                       System.Threading.Thread.Sleep(2000);

                       string ssss = manList.Substring(0, 1);

                       if (ssss != "T")

                       {

                            temps = manList.Split(',');

                           

                   this.comboBox1.Invoke(this.myUpdateList2);//由于新开启的线程无法控制主线程的控件所以这里要用到一个委托

//用控件的的Invoke方法才能对主线程的控件进行控制

                        }

                       else

                       {

                       //由于新开启的线程无法控制主线程的控件所以这里要用到一个委托

this.textBox2.Invoke(this.myUpdatetext1,manList);//用控件的的Invoke方法才能对主线程的控件进行控制

                       }

                    }

              }

 

              catch (Exception e)

              {

                   MessageBox.Show(e.ToString());

                   Console.Write("");

              }

}

     }

}