转自:http://blog.csdn.net/liguo9860/article/details/6148614
- //实现服务器端
- //创建Client类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ChartServer
- {
- /// <summary>
- /// 客户端连接
- /// </summary>
- class Client
- {
- #region 字段
- //客户端连接线程
- private System.Threading.Thread clthread;
- //客户端连接网络地址
- private System.Net.EndPoint endpoint;
- //客户端名称
- private string name;
- //客户端对象
- private System.Net.Sockets.Socket sock;
- #endregion
- #region 构造
- //构造一个客户端连接
- public Client(string _name, System.Net.EndPoint _endpoint, System.Threading.Thread _thread, System.Net.Sockets.Socket _sock)
- {
- clthread = _thread;
- endpoint = _endpoint;
- name = _name;
- sock = _sock;
- }
- #endregion
- #region 方法
- //重写ToString方法
- public override string ToString()
- {
- //返回客户端连接网络地址和客户端连接名称
- return endpoint.ToString() + ":" + name;
- }
- #endregion
- #region 属性
- public System.Threading.Thread CLThread
- {
- get { return clthread; }
- set { clthread = value; }
- }
- public System.Net.EndPoint Host
- {
- get { return endpoint; }
- set { endpoint = value; }
- }
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
- public System.Net.Sockets.Socket Sock
- {
- get { return sock; }
- set { sock = value; }
- }
- #endregion
- }
- }
- //服务器端代码
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- namespace ChartServer
- {
- public partial class ServerMain : Form
- {
- public ServerMain()
- {
- InitializeComponent();
- }
- //客户端连接
- System.Net.Sockets.Socket clientsocket;
- //连接集合
- System.Collections.ArrayList clients;
- //客户端线程
- System.Threading.Thread clientservice;
- System.Threading.Thread threadListen;
- System.Net.Sockets.TcpListener listener;
- System.Net.IPAddress ipAddress;
- Int32 listenport;
- public delegate void MyInvoke(string str);
- /// <summary>
- /// 开始侦听,允许客户端连接
- /// </summary>
- private void StartListening()
- {
- //定义网络连接侦听
- listener = new System.Net.Sockets.TcpListener(ipAddress,listenport);
- listener.Start();
- while (true)
- {
- try
- {
- //开始侦听网络连接
- clientsocket = listener.AcceptSocket();
- //客户端连接线程
- clientservice = new System.Threading.Thread(new System.Threading.ThreadStart(ServiceClient));
- //启动线程
- clientservice.Start();
- }
- catch (Exception e)
- {
- MessageBox.Show("listening Error:" + e.Message);
- }
- }
- }
- private void ServiceClient()
- {
- //获取一个客户端连接
- System.Net.Sockets.Socket client = clientsocket;
- //定义一个是否存活的变量
- bool keepalive = true;
- //判断新连接是否存在
- if (client == null) keepalive = false;
- else keepalive = true;
- //判断客户端是否还存在
- while (keepalive)
- {
- //定义字节
- Byte[] buffer = new Byte[1024];
- //定义数据量
- int bufLen = 0;
- try
- {
- //从客户端接收到的数据量
- bufLen = client.Available;
- //接收客户端发过来的数据
- client.Receive(buffer, 0, bufLen, System.Net.Sockets.SocketFlags.None);
- //假如客户端没有传入数据,则返回
- if (bufLen == 0) continue;
- //将字节转换为字符串
- string clientcommand = System.Text.Encoding.ASCII.GetString(buffer).Substring(0, bufLen);
- //分割从客户端传入的字符串
- string[] tokens = clientcommand.Split(new Char[] { '|' });
- //输出到控制台
- Console.WriteLine(clientcommand);
- //CONN:表示新建连接。发送格式:CONN|发送者名称
- if (tokens[0] == "CONN")
- {
- //循环所有的客户端
- for (int n = 0; n < clients.Count; n++)
- {
- //循环获取连接对象
- Client cl = (Client)clients[n];
- //向所有客户端发送新添加连接消息
- SendToClient(cl, "JOIN|" + tokens[1]);
- }
- //获取新添加连接的网络地址
- System.Net.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);
- //创建线程 将新连接添加到当前连接集合中,使用匿名委托调用添加方法
- System.Threading.Thread handlerControl = new System.Threading.Thread(delegate() { handlerListBox(c.Name + "|" + c.Host.ToString(), "add"); });
- //启动线程
- handlerControl.Start();
- }
- //CHAT:发送全局消息,所有其他连接都可以接收到。发送格式:CHAT|发送者名称|信息内容
- if (tokens[0] == "CHAT")
- {
- //循环连接集合
- for (int n = 0; n < clients.Count; n++)
- {
- //获取当前连接
- Client cl = (Client)clients[n];
- //发送消息
- SendToClient(cl, clientcommand);
- }
- }
- //PRIV:发送私聊信息。发送格式:PRIV|发送者名称|信息内容|接受者名称
- if (tokens[0] == "PRIV")
- {
- //获取接受者连接名称
- string destclient = tokens[3];
- //循环集合列表
- for (int n = 0; n < clients.Count; n++)
- {
- //获取连接
- Client cl = (Client)clients[n];
- //如果是接受者
- if (cl.Name.CompareTo(tokens[3]) == 0)
- //发送消息
- SendToClient(cl, clientcommand);
- //如果是发送者
- if (cl.Name.CompareTo(tokens[1]) == 0)
- //发送消息
- SendToClient(cl, clientcommand);
- }
- }
- //GONE 退出。发送格式:GONE|发送者名称
- if (tokens[0] == "GONE")
- {
- //连接索引
- int remove = 0;
- //是否存在
- bool found = false;
- //当前连接数
- int c = clients.Count;
- //连接名称
- string clientname = "";
- //遍历集合
- for (int n = 0; n < clients.Count; n++)
- {
- //获取连接
- Client cl = (Client)clients[n];
- //如果不是要退出的连接
- if (cl.Name.CompareTo(tokens[1]) != 0)
- //发送消息
- SendToClient(cl, clientcommand);
- else
- {
- //发送确认退出信息
- SendToClient(cl, "QUIT|");
- //获取连接名称
- clientname = cl.Name + "|" + cl.Host.ToString();
- //获取连接索引
- remove = n;
- //连接存在
- found = true;
- }
- }
- //连接存在
- if (found)
- {
- //创建删除连接线程,从列表中删除连接
- System.Threading.Thread t = new System.Threading.Thread(delegate() { handlerListBox( clientname, "del"); });
- //启动线程
- t.Start();
- //从集合中删除连接
- clients.RemoveAt(remove);
- //改变存活状态
- keepalive = false;
- }
- }
- }
- catch (Exception e)
- {
- MessageBox.Show("Receive Error:" + e.Message);
- keepalive = false;
- }
- }
- }
- /// <summary>
- /// 获取当前连接集合
- /// </summary>
- /// <returns></returns>
- private string GetChatterList()
- {
- string result = "";
- //循环集合,获取连接名称。
- for (int i = 0; i < clients.Count; i++)
- {
- //使用“|”分隔
- result += ((Client)clients[i]).Name + "|";
- }
- return result;
- }
- /// <summary>
- /// 发送信息到客户端
- /// </summary>
- /// <param name="cl">客户端连接</param>
- /// <param name="clientCommand">要发送的信息</param>
- private void SendToClient(Client cl, string clientCommand)
- {
- //将字符串转换成字节
- Byte[] message = System.Text.Encoding.ASCII.GetBytes(clientCommand);
- //获取连接对象
- System.Net.Sockets.Socket s = cl.Sock;
- //判断是否还在连接状态
- if (s.Connected)
- {
- //发送消息
- s.Send(message, message.Length, 0);
- }
- }
- /// <summary>
- /// 加载窗体类
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void ServerMain_Load(object sender, EventArgs e)
- {
- //创建连接集合
- clients = new System.Collections.ArrayList();
- }
- /// <summary>
- /// 监听按钮
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStartListening_Click(object sender, EventArgs e)
- {
- this.btnStartListening.Enabled = false;
- //获取服务器端IP地址
- ipAddress = System.Net.IPAddress.Parse("192.168.104.110");
- //获取服务器端口号
- listenport = 6666;
- //创建监听线程
- threadListen = new System.Threading.Thread(StartListening);
- //启动线程
- threadListen.Start();
- //创建设置状态文本线程
- System.Threading.Thread handlerControl = new System.Threading.Thread( delegate() { SetText("Listening..."); });
- //启动线程
- handlerControl.Start();
- }
- /// <summary>
- /// 设置连接文本
- /// </summary>
- /// <param name="s"></param>
- private void SetText(string s)
- {
- //判断是否是本线程调用
- if (lblMessage.InvokeRequired)
- {
- //如果不是,则使用委托,改变为本线程调用
- MyInvoke _myInvoke = new MyInvoke(SetText);
- //执行委托,传入参数
- this.Invoke(_myInvoke, new object[] { s });
- }
- else
- {
- //改变文本值
- this.lblMessage.Text = s;
- }
- }
- private void handlerListBox(string c, string o)
- {
- //判断是否是本线程调用
- if (lbClients.InvokeRequired)
- {
- //创建委托
- MyInvoke _myInvoke;
- //要执行的操作
- if (o == "add")
- _myInvoke = new MyInvoke(addItem);
- else
- _myInvoke = new MyInvoke(delItem);
- //执行委托,将参数传入
- this.Invoke(_myInvoke, new object[] { c });
- }
- }
- /// <summary>
- /// 在当前连接列表中删除一个连接
- /// </summary>
- /// <param name="c"></param>
- private void delItem(string c)
- {
- this.lbClients.Items.Remove(c);
- }
- /// <summary>
- /// 在当前连接列表中新建一个连接
- /// </summary>
- /// <param name="c"></param>
- private void addItem(string c)
- {
- this.lbClients.Items.Add(c);
- }
- }
- }
下载地址:示例代码下载