利用TCP协议通过Socket编写的网络聊天工具3-服务器端设计
服务器端的设计因为包含界面,所以启动一个新的线程监听端口,然后每次接受一个Socket以后启动一个新的连接Socket的线程。
整个项目的源代码,稍后给出下载连接。
整个项目源码下载地址: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协议); 支持离线消息(基于TCP协议); 支持点到点可靠文件传输(基于UDP协议); 存储在服务器端的数据...
为实现网络聊天的功能,采用Windows Socket编程,服务器与客户端采用了TCP/IP连接方式,在设计聊天方案时,实行将所有信息发往服务器端,再由服务器进行分别处理的思路,服务器端是所有信息的中心。 由于服务器端要...
算机网络编程的基本理论知识如TCP/IP协议、客户端/服务器端模式 (Client/Server模式)、网络编程的设计方法等。在网络编程中对信息的读 取、发送,是利用流来实现信息的交换,其中介绍了对实现一个系统的信息流 的...
开发中利用了计算机网络编程的基本理论知识,如TCP/IP协议、客户端/服务器端模式(Client/Server模式)、网络编程的设计方法等。在网络编程中对信息的读取、发送,是利用流来实现信息的交换,其中介绍了对实现一个...
开发中利用了计算机网络编程的基本理论知识,如TCP/IP协议、客户端/服务器端模式(Client/Server模式)、网络编程的设计方法等。在网络编程中对信息的读取、发送,是利用流来实现信息的交换,其中介绍了对实现一个...
使用Python代码编写的基于TCP/IP的网络聊天室。此程序有两部分,一是服务端,一是客户端。服务端为模拟服务器,用来固定 ip 和端 口。如果客户端连接过来,服务器就与该客户端建立 Socket 连接,随后的通信就靠 ...
开发中利用了计算机网络编程的基本理论知识,如TCP/IP协议、客户端/服务器端模式(Client/Server模式)、网络编程的设计方法等。在网络编程中对信息的读取、发送,是利用流来实现信息的交换,其中介绍了对实现一个...
全书共分13章,主要内容包括网络编程原理、Visual C# 2005的套接字以及多线程的开发、基于各种不同协议的网络编程应用模块,并通过几个典型的实例介绍了Visual C# 2005网络编程的实际应用。 本书注重代码的通用性和...
开发中利用了计算机网络编程的基本理论知识,如TCP/IP协议、客户端/服务器端模式(Client/Server模式)、网络编程的设计方法等。在网络编程中对信息的读取、发送,是利用流来实现信息的交换,其中介绍了对实现一个...
网络程序设计实验一 熟悉开发工具 1 实验二 套接字编程练习 6 实验三 TCP套接字编程 18 实验四 UDP组播程序编程 25 实验五 基于MFC Socket类的网络编程 29 实验六 聊天室程序的设计及实现 35 实验七 PING程序的设计...
基于tcp/udp协议的socket编程 4.1 hternet和socket简介 4.1.1 tcp协议简介 4.1.2 udp协议简介 4.1.3 端口简介 4.1.4 system.net名称空间 4.1.5 system.net.sockets名称空间 4.2 基于tcp协议的...
内含远程控制、进程管理、文件操作、视频控制、注册表操作、客户端服务器端。 redui_src_v0.9.130(DirectUI 3D) DirectUI 3D界面库。 sdk(界面库) RINGSDK包含界面库和图象库。 绘MFC基本控件 ) 如题。 ...
内容简介《Linux高性能服务器编程》是Linux服务器编程领域的经典著作,由资深Linux软件开发工程师撰写,从网络协议、服务器编程核心要素、原理机制、工具框架等多角度全面阐释了编写高性能Linux服务器应用的方法、...
tCP/IP网络同步通信,类QQ网络即时聊天工具,服务器端和客户端界面和程序编写。
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 ...
2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。...
2个目标文件 摘要:Java源码,文件操作,TCP,服务器 Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。...
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...