关于多线程的概念大家在编写程序的时候会经常的碰到。下边我就用一个多点通讯的例子来说明一下如何使用线程。
首先介绍服务器的代码主界面代码:
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)//通过名称得到name的id;
{
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("");
}
}
}
}
浙公网安备 33010602011771号