查看文章 |
C#多线程编程---一个简单的聊天程序(Server)
2008-06-29 11:14
这两天公司要求做一个聊天软件,要求基于Socket---TCP协议的。本人偷懒到网上一搜,好多阿!可后来仔细一看其实只有一个还算沾边。于是就下载下来,但是编译、运行都有问题。后来又找了好几个,都是一样的。估计就是大家你抄袭我的我抄袭他的,谁也没有真正的编译运行一下。结果看似挺好的软件,实际上根本不能运行。 于是我用了一天的时间(其实没有这么多。)把它们整理了一下,基本上主要功能可以运行了。下面把它贴到网上供大家参考。 服务器端:
![]() (1)Form1.cs[设计]界面 (2)Form1.cs[代码] 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; using System.Net.Sockets; using System.Threading; using System.Collections; namespace ChatServer { public partial class Form1 : Form { static int listenport = 8000; Socket clientsocket; Thread clientservice; ArrayList clients; Thread threadListen; TcpListener listener; delegate void AddListCallBack(string TextContext); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { clients = new ArrayList(); } private void StartListening() { listener = new TcpListener(IPAddress.Parse("127.0.0.1"),listenport); listener.Start(); while (true) { try { Socket s = listener.AcceptSocket(); clientsocket = s; clientservice = new Thread(new ThreadStart(ServiceClient)); clientservice.Start(); //MessageBox.Show(clientservice.ToString()); } catch (Exception e) { Console.WriteLine(e.ToString()); } } } private void ServiceClient() { Socket client = clientsocket; bool keepalive = true; while (keepalive) { Byte[] buffer = new Byte[1024]; client.Receive(buffer); string clientcommand = System.Text.Encoding.ASCII.GetString(buffer); string[] tokens = clientcommand.Split(new Char[]{'|'}); Console.WriteLine(clientcommand); if (tokens[0] == "CONN") { for (int n = 0; n < clients.Count; n++) { Client cl = (Client)clients[n]; SendToClient(cl, "JOIN|" + tokens[1]); } EndPoint ep = client.RemoteEndPoint; Client c = new Client(tokens[1], ep, clientservice, client); clients.Add(c); string message = "LIST|" + GetChatterList() +"\r\n"; SendToClient(c, message); AddList(c.ToString()); //listBox1.Items.Add(c); } if (tokens[0] == "CHAT") { for (int n = 0; n < clients.Count; n++) { Client cl = (Client)clients[n]; SendToClient(cl, clientcommand); } } if (tokens[0] == "PRIV") { string destclient = tokens[2]; for(int n=0; n < clients.Count;n++) { Client cl = (Client)clients[n]; if(cl.Name.CompareTo(tokens[2]) == 0) SendToClient(cl, clientcommand); // if(cl.Name.CompareTo(tokens[1]) == 0) // SendToClient(cl, clientcommand); } } if (tokens[0] == "GONE") { int remove = 0; bool found = false; int c = clients.Count; for (int n = 0; n < clients.Count; n++) { Client cl = (Client)clients[n]; SendToClient(cl, clientcommand); if(cl.Name.CompareTo(tokens[1]) == 0) { remove = n; found = true; //listBox1.Items.Remove(cl); } //cl.CLThread.Abort(); } if(found) clients.RemoveAt(remove); client.Close(); keepalive = false; } } } private void SendToClient(Client cl, string clientCommand) { Byte[] message = System.Text.Encoding.ASCII.GetBytes(clientCommand); Socket s = cl.Sock; if(s.Connected) { s.Send(message, message.Length, 0); } } private string GetChatterList() { string result = ""; for (int i = 0; i < clients.Count; i++) { result += ((Client)clients[i]).Name + "|"; } return result; } private void AddList(string textContext) { if (this.listBox1.InvokeRequired) { AddListCallBack d = new AddListCallBack(AddList); this.Invoke(d,new object[]{textContext}); } else { this.listBox1.Items.Add(textContext); } } private void button1_Click(object sender, EventArgs e) { threadListen = new Thread(new ThreadStart(StartListening)); threadListen.Start(); label1.Text = "listening...."; } private void button2_Click(object sender, EventArgs e) { listener.Stop(); threadListen.Abort(); threadListen.Join(); label1.Text = "END...."; } } } (3)Form1.Designer.cs using System; namespace ChatServer { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing) { if (clientservice != null) { clientservice.Abort(); } if (threadListen != null) { try { threadListen.Abort(); } catch (Exception ex) { threadListen = null; } } if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.listBox1 = new System.Windows.Forms.ListBox(); this.button1 = new System.Windows.Forms.Button(); this.label1 = new System.Windows.Forms.Label(); this.button2 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // listBox1 // this.listBox1.FormattingEnabled = true; this.listBox1.ItemHeight = 12; this.listBox1.Location = new System.Drawing.Point(1, 3); this.listBox1.Name = "listBox1"; this.listBox1.Size = new System.Drawing.Size(289, 220); this.listBox1.TabIndex = 0; // // button1 // this.button1.Location = new System.Drawing.Point(137, 229); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(68, 28); this.button1.TabIndex = 1; this.button1.Text = "START"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(12, 237); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(41, 12); this.label1.TabIndex = 2; this.label1.Text = "label1"; // // button2 // this.button2.Location = new System.Drawing.Point(211, 229); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(70, 28); this.button2.TabIndex = 3; this.button2.Text = "END"; this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(293, 268); this.Controls.Add(this.button2); this.Controls.Add(this.label1); this.Controls.Add(this.button1); this.Controls.Add(this.listBox1); this.Name = "Form1"; this.Text = "聊天软件服务器"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.ListBox listBox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button2; } } (4)Client.cs Client Class using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace ChatServer { using System.Net.Sockets; using System.Net; class Client { private Thread clthread; private EndPoint endpoint; private string name; private Socket sock; public Client(string _name, EndPoint _endpoint, Thread _thread, Socket _sock) { // TODO: 在此处添加构造函数逻辑 clthread = _thread; endpoint = _endpoint; name = _name; sock = _sock; } public override string ToString() { return endpoint.ToString()+ " : " + name; } public Thread CLThread { get{return clthread;} set{clthread = value;} } public EndPoint Host { get{return endpoint;} set{endpoint = value;} } public string Name { get{return name;} set{name = value;} } public Socket Sock { get{return sock;} set{sock = value;} } } } 注:成员列表刷新有问题,没有解决。 如果你还看到别的问题,请连同解决代码一起给我。我会及时更新的。 Email:jobsmeng@QQ.com 谢谢!! |
最近读者:
