利用TCP协议通过Socket编写的网络聊天工具3-服务器端设计
2012-05-14 16:53
597 查看
服务器端的设计因为包含界面,所以启动一个新的线程监听端口,然后每次接受一个Socket以后启动一个新的连接Socket的线程。
整个项目的源代码,稍后给出下载连接。
整个项目源码下载地址:http://download.csdn.net/detail/weixingstudio/4301232
整个项目的源代码,稍后给出下载连接。
整个项目源码下载地址:http://download.csdn.net/detail/weixingstudio/4301232
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; using UtilityClass; using System.Net; using System.Net.Sockets; using System.Collections; using System.Threading; using System.Collections.Specialized; namespace ChatPlatform { public partial class ServerMain : Form { IPAddress serverIPAddress; TcpListener serverListener; private ServerConfig serverConfig; private string _serverIP="10.108.13.27"; private int _serverPort = 8888; private int userCount = 0; private Hashtable onlineUserHashtable; Thread serverListenThread; private delegate void setSystemLogDelegate(string s); private delegate void setOnlineUserDelegate(string s); public ServerMain() { InitializeComponent(); serverConfig = new ServerConfig(_serverIP,_serverPort); onlineUserHashtable = new Hashtable(); this.systemlog.ScrollToCaret(); this.button_stop.Enabled = false; } private void serverConfigButton_Click(object sender, EventArgs e) { int flag = 0; ServerConfigurationForm configForm = new ServerConfigurationForm(serverConfig); configForm.ShowDialog(); if (ServerConfigurationForm.Result) { MessageBox.Show("修改配置成功!"); } } private void button_start_Click(object sender, EventArgs e) { if (serverListenThread!=null) { // 服务已经开启了 MessageBox.Show("服务已经开启!"); } else { // 开启一个新线程,监听用户连接请求 onlineUserHashtable.Clear(); // 清理在线用户列表 //this.systemlog.Clear(); serverListenThread = new Thread(new ThreadStart(PortListenFunc)); serverListenThread.IsBackground = true; serverListenThread.Start(); this.button_stop.Enabled = true; this.button_start.Enabled = false; } } /// <summary> /// 在一个线程中监听端口连接请求 /// </summary> /// <param name="obj"></param> private void PortListenFunc() { // try { serverIPAddress = IPAddress.Parse(serverConfig.ServerIP); serverListener = new TcpListener(serverIPAddress, serverConfig.ServerPort); serverListener.Start();// 开始监听 RefreshSystemlog("listen port " + serverConfig.ServerPort + " started!."+DateTime.Now); RefreshSystemlog("server IP:" + serverConfig.ServerIP); RefreshSystemlog("server port:" + serverConfig.ServerPort); //开始循环监听端口,接收用户连接 while (true) { byte[] receiveBuffer = new byte[serverConfig.MaxBuffer]; Socket newClient = serverListener.AcceptSocket(); if (onlineUserHashtable.Count<serverConfig.MaxAllowedOnlineUser) { //Socket newClient = serverListener.AcceptTcpClient(); newClient.Receive(receiveBuffer); string userName = Command.DecodeCommand(receiveBuffer); // 验证用户名的有效性 if (onlineUserHashtable.Count != 0 && onlineUserHashtable.ContainsKey(userName)) { newClient.Send(Command.EncodeCommand(Command.RedundantUserName)); } else { // 用户名有效 onlineUserHashtable.Add(userName, newClient); newClient.Send(Command.EncodeCommand(Command.ConnectConfirm)); RefreshSystemlog("用户:" + userName + "登录系统" + DateTime.Now); Thread clientThread = new Thread(new ParameterizedThreadStart(clientFunc)); clientThread.IsBackground = true; clientThread.Start(userName); Thread.Sleep(300); // 通知所有在线用户,有人上线了 foreach (DictionaryEntry de in onlineUserHashtable) { string name = de.Key as string; Socket socket = de.Value as Socket; //if (!name.Equals(userName)) if (true) { // 发送命令 byte[] cmd_byte = Command.EncodeCommand(Command.SomeoneConnected); socket.Send(cmd_byte); // 发送用户名 cmd_byte = Command.EncodeCommand(userName); socket.Send(cmd_byte); } } // 更新在线用户列表 FlashOnlineUser(); } } else { // 超出了允许的最大连接数 newClient.Receive(receiveBuffer); string userName = Command.DecodeCommand(receiveBuffer); newClient.Send(Command.EncodeCommand(Command.ExceedMaxAllowedNumber)); } } } catch (System.Exception ex) { // 监听端口出错,关闭服务 RefreshSystemlog("监听端口出错" + DateTime.Now); RefreshSystemlog("服务关闭!"); RefreshSystemlog(ex.Message); if (serverListener!=null) { serverListener.Stop(); serverListener = null; } } } /// <summary> /// 处理每一个连接的客户端的事务 /// </summary> /// <param name="obj"></param> private void clientFunc(object obj) { string userName = obj as string; // 获取与客户端通信的套接字 Socket clientSocket = onlineUserHashtable[obj] as Socket; while (true) { if (clientSocket.Connected) { try { byte[] cmdBuffer = new byte[serverConfig.MaxBuffer]; clientSocket.Receive(cmdBuffer); // 获取传送过来的命令 string cmd_from_client = Command.DecodeCommand(cmdBuffer); switch (cmd_from_client) { // 请求离开 case Command.DisConnect: { onlineUserHashtable.Remove(obj); RefreshSystemlog("用户:" + userName + "离开系统!" + DateTime.Now); FlashOnlineUser(); // 给所有用户发消息,某人离开 foreach (DictionaryEntry de in onlineUserHashtable) { Socket s = de.Value as Socket; byte[] cmd = Command.EncodeCommand(Command.SomeoneLeave); // 发送命令 s.Send(cmd); Thread.Sleep(50); cmd = Command.EncodeCommand(userName); // 发送用户名 s.Send(cmd); } Thread.CurrentThread.Abort(); break; } // 用户请求在线用户列表 case Command.RequestOnlineUser: { byte[] cmd = new byte[serverConfig.MaxBuffer]; string[] user = new string[onlineUserHashtable.Count]; int i = 0; foreach (DictionaryEntry de in onlineUserHashtable) { user[i] = de.Key as string; i++; } // 发送命令 clientSocket.Send(Command.EncodeCommand(Command.SendOnlinUserList)); cmd = Command.SerializeOnlineUser(user); // 发送在线用户列表 clientSocket.Send(cmd); break; } // 请求对所有用户广播消息 case Command.BroadcastAll: { byte[] cmd = new byte[serverConfig.MaxBuffer]; clientSocket.Receive(cmd); Thread.Sleep(50); foreach (DictionaryEntry de in onlineUserHashtable) { Socket socket = de.Value as Socket; string name = de.Key as string; if (!name.Equals(userName)) { //向所有用户广播消息 socket.Send(Command.EncodeCommand(Command.BroadcastAll)); Thread.Sleep(20); // 发送广播消息的用户名 socket.Send(Command.EncodeCommand(userName)); Thread.Sleep(20); // 发送要广播的消息 socket.Send(cmd); } } break; } // 请求对某个对象发送数据 case Command.SendMessage2One: { // 接收对象名 byte[] cmd = new byte[serverConfig.MaxBuffer]; clientSocket.Receive(cmd); string name_private = Command.DecodeCommand(cmd); Thread.Sleep(50); // 接收数据 byte[] data = new byte[serverConfig.MaxBuffer]; clientSocket.Receive(data); Thread.Sleep(50); // 发送数据到目标对象 Socket socket = onlineUserHashtable[name_private] as Socket; // 发送命令 socket.Send(Command.EncodeCommand(Command.SendMessage2One)); Thread.Sleep(50); // 发送用户名 socket.Send(Command.EncodeCommand(userName)); Thread.Sleep(50); socket.Send(data); break; } // 对某个用户抖动 case Command.VibrateOne: { byte[] cmd = new byte[serverConfig.MaxBuffer]; clientSocket.Receive(cmd); string name_private = Command.DecodeCommand(cmd); Socket socket = onlineUserHashtable[name_private] as Socket; // 发送抖动命令 socket.Send(Command.EncodeCommand(Command.VibrateOne)); Thread.Sleep(20); // 发送用户名 socket.Send(Command.EncodeCommand(userName)); break; } // 对所有人闪屏 case Command.VibrateAll: { // 发送命令 foreach (DictionaryEntry de in onlineUserHashtable) { Socket socket = de.Value as Socket; string name = de.Key as string; if (!name.Equals(userName)) { socket.Send(Command.EncodeCommand(Command.VibrateAll)); Thread.Sleep(20); socket.Send(Command.EncodeCommand(userName)); } } break; } default: { break; } } } catch (System.Exception ex) { // 某个客户端连接发生异常 onlineUserHashtable.Remove(obj); // 向所有连接发送消息 foreach (DictionaryEntry de in onlineUserHashtable) { Socket s = de.Value as Socket; byte[] cmd = Command.EncodeCommand(Command.SomeoneLeaveUnexpected); s.Send(cmd); cmd = Command.EncodeCommand(userName); s.Send(cmd); } Thread.CurrentThread.Abort(); } } else { // 没有连接则终止线程 Thread.CurrentThread.Abort(); } } } /// <summary> /// 线程安全的更新在线用户列表 /// </summary> private void FlashOnlineUser() { Action clearOnlineList = delegate() { this.onlineuserlistbox.Items.Clear(); }; this.onlineuserlistbox.Invoke(clearOnlineList); foreach (DictionaryEntry de in onlineUserHashtable) { string name = de.Key as string; if (this.onlineuserlistbox.InvokeRequired) { setOnlineUserDelegate call = delegate(string s) { this.onlineuserlistbox.Items.Add(s); }; this.onlineuserlistbox.Invoke(call,name); } else { this.onlineuserlistbox.Items.Add(name); } } } /// <summary> /// 线程安全的添加系统日志信息 /// </summary> /// <param name="log"></param> private void RefreshSystemlog(string log) { if (this.systemlog.InvokeRequired) { setSystemLogDelegate call = delegate(string s) { this.systemlog.Text += s + "\n"; }; this.systemlog.Invoke(call,log); } else { this.systemlog.Text += log + "\n"; } //this.systemlog.Select(this.systemlog.Text.Length, 0); //this.systemlog.ScrollToCaret(); } private void button_stop_Click(object sender, EventArgs e) { if (serverListener!=null) { serverListener.Stop(); RefreshSystemlog("listen port "+serverConfig.ServerPort+" stopped!"+DateTime.Now); serverListenThread.Abort(); if (onlineUserHashtable.Count!=0) { // 清理所有的连接 foreach (DictionaryEntry de in onlineUserHashtable) { Socket s = de.Value as Socket; byte[] cmd = Command.EncodeCommand(Command.ServerShutdown); s.Send(cmd); //Thread.Sleep(50); // 关闭和客户端的连接 s.Close(); } onlineUserHashtable.Clear(); // 清除用户列表 } RefreshSystemlog("清理连接用户完毕!" + DateTime.Now); serverListener = null; serverListenThread = null; this.button_stop.Enabled = false; this.button_start.Enabled = true; } else { RefreshSystemlog("端口监听已经结束!" + DateTime.Now); } } /// <summary> /// 用户点击关闭按钮 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void stopService(object sender, FormClosingEventArgs e) { //this.Owner.Close(); //if (serverListener!=null) //{ // serverListener.Stop(); // serverListener = null; // RefreshSystemlog("service stopped!"); // serverListenThread.Abort(); // serverListenThread.Join(); // serverListenThread = null; //} } private void systemlog_TextChanged(object sender, EventArgs e) { this.systemlog.SelectionStart = this.systemlog.TextLength; this.systemlog.ScrollToCaret(); } } }
相关文章推荐
- 利用TCP协议通过Socket编写的网络聊天工具2-通用类设计
- 利用TCP协议通过Socket编写的网络聊天工具1-客户端
- 利用TCP传输协议实现基于Socket的聊天程序
- 利用TCP和UDP协议,实现基于Socket的小聊天程序
- Socket网络程序设计(3) ———— 利用tcp完成文件传输的设计和实现
- 利用TCP和UDP协议,实现基于Socket的小聊天程序(初级版)
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
- 在C++ Builder中用socket api来写网络通讯程序(同时支持TCP和UDP协议)(二)
- MFC Socket网络编程之TCP服务器端
- 网络协议的详细讲解,Socket和TCP/IP还有HTTP
- 利用协议分析工具学习TCP/IP并捕获内网用户密码
- Python网络通信之socket模块(四)基于Tcp/Ip的TCP交互通信serve/client的编写过程
- 网络协议:TCP/IP、UDP、Http、Socket
- [置顶] JAVA进阶案例 TCP编程之网络聊天工具(服务端)
- 实现记录和查看用户的系统登录和退出历史和利用C#编写的网络聊天程序
- java网络编程之Tcp协议下的聊天小程序
- 常见网络协议相关总结socket, TCP/IP
- 网络-利用抓包工具理解TCP三次握手
- 利用TCP Socket编程开发网络游戏(一)