设计一个网络聊天室,能够显示有关该系统基本信息的描述,如:客户端的实例信息、在线等,具体要求如下:

(1)聊天室服务器端的创建

(2)聊天室客户端的创建

(3)实现客户与服务器的连接通讯

(4)实现客户之间的私聊

(5)实现客户端的在线信息显示

该系统用户信息存储在文本文件中,当客户端启动时,客户端发送客户输入的账号和密码到服务端,服务端将客户端发送的账号与密码与文件中的信息对比,若成功,将第二个|后面的字符串改为succeed, 由客户端审核第二个|后的字符串是否succed, 若是在将用户名进行判断,判断在线客户列表中是否已经有该名字,若有就显示登录失败,若无,则进入聊天模式,在线客户列表加入此用户

通过套字节设置,采用TCP通讯,用户选择发送对象为ALL,点击发送,系统将信息从客户端发送到服务端,服务端将信息发送到当前在线的所有用户

 

点击刷新在人数,获取在线用户列表,并更新在线人数,刷新在线人数

 

 

客户端

当前客户端UI设计将登录界面和聊天界面合二为一,整体大都采用蓝色,风格简洁,字体为”字魂110号-武林江湖体, 9pt”,整体用户在确认服务端开启且未登录的情况下,用户只能使用登录界面的控件,待用户登录成功后,登录界面的控件设为只读模式

 服务端

服务端页面整体色调为蓝色,包括IP地址,端口的显示,可以显示在线人数,以及连接信息,点击刷新在线人数,可以显示当前在线人数

 

用户数据存储方式

本系统采用的是文本文件的方式存储用户,存储路径为:”C:\Users\黄**\Desktop\课程设计\ChatRoom-master\可执行文件\user”, 文件地址显示如图4-1-1所示。

 源码:

客户端部分:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Threading;using System.Net.Sockets;using System.Net;using Newtonsoft.Json;namespace ChatRoom.Client{public partial class ClientForm : Form{//string rs;public ClientForm(){showMsg = new ShowMsg(appendMsg);addItem = new AddItem(addItemToComboBox);deleteItem = new DeleteItem(deleteItemFromComboBox);InitializeComponent();}#region -----------------------1. Socket处理IPAddress address = null;Socket clientSocket = null;IPEndPoint endPoint = null;private void connecToServer(){try{//创建客户端套接字clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);address = IPAddress.Parse("127.0.0.1");endPoint = new IPEndPoint(address, 9000);//连接服务器clientSocket.Connect(endPoint);}catch (Exception e){string errStr = string.Format("系统提示:出现了错误!\r\n错误信息:{0}\r\n", e.Message);textBox_CLIENT_MSG.AppendText(errStr);return;}}/// /// 获取服务器发送过来的数据/// private string recvMsg(){try{byte[] receveMsg = new byte[1024 * 1024 * 2];int length = clientSocket.Receive(receveMsg);return Encoding.UTF8.GetString(receveMsg, 0, length);}catch (Exception e){return e.Message;}}/// /// 描述:发送数据到服务器进行处理/// /// private void sendMsg(string msg){try{clientSocket.Send(Encoding.UTF8.GetBytes(msg));}catch (Exception ex){showDialog("Error:"+ex.Message);}}#endregion #region -----------------------2. 发送消息/// --------------------------------------------/// /// 描述:发送消息/// /// /// /// --------------------------------------------private void button_SEND_Click(object sender, EventArgs e){try{//连接服务器成功发送消息string msg = textBox_CLIENT_SEND_MSG.Text.ToString();string logininUser = textBox_hide.Text;if (string.IsNullOrEmpty(logininUser)){showDialog("您还没登录");return;}if (string.IsNullOrEmpty(msg)){showDialog("发送内容不能为空");return;}string toUser = comboBox_USER_LIST.Text.ToString();if (string.IsNullOrEmpty(toUser)){showDialog("请选择发送对象!");return;}string sendStrMsg = "Talk|" + textBox_hide.Text.ToString() + "|" + toUser + "|" + msg;sendMsg(sendStrMsg); // sendMsg(rs); textBox_CLIENT_SEND_MSG.Text = "";textBox_CLIENT_MSG.AppendText("\r\n"+"你对" + toUser + "说:" + msg +"\r\n");}catch (Exception ex){//出现异常,如:没有连接到服务器string errorMsg = string.Format(@"发送失败:{0}", ex.Message);textBox_CLIENT_MSG.AppendText(errorMsg + "\r\n");}}#endregion#region -----------------------3. 登录/// --------------------------------------------/// /// 描述:登录/// /// /// /// --------------------------------------------private void button_Login_Click(object sender, EventArgs e){string username = textBox_UserName.Text.ToString();string pwd = textBox_Pwd.Text.ToString();if (!checkInput(username, pwd)) return;connecToServer();string requestLoginMsg = string.Format(@"Login|{0}|{1}", username, pwd);try{sendMsg(requestLoginMsg);//初始化登录initLogin();}catch (Exception ex){showDialog("登录失败");return;}}private void initLogin(){string strRecvMsg = recvMsg();string[] strArray = strRecvMsg.Split('|');switch (strArray[0]){ case "login":if (strArray[1].Equals("succeed")){string user = textBox_UserName.Text;button_Login.Dispose();button_Register.Dispose();textBox_Pwd.Dispose();textBox_UserName.Dispose();label2.Dispose();label3.Dispose();label_hide.Show();textBox_hide.Text = user;textBox_hide.Show();//启动客户端与服务器的连接服务new ClientService(clientSocket, this);string strSendMsg = "Init|online";sendMsg(strSendMsg);}break;case "warning":string warningMsg = this.recvMsg();showDialog(warningMsg.Split('|')[1]);clientSocket.Shutdown(SocketShutdown.Both);clientSocket.Close();clientSocket = null;break;}}#endregion#region -----------------------4. 注册/// --------------------------------------------/// /// 描述:注册/// /// /// /// --------------------------------------------private void button_Register_Click(object sender, EventArgs e){string username = textBox_UserName.Text.ToString();string pwd = textBox_Pwd.Text.ToString();if (!checkInput(username, pwd)) return;connecToServer();string requestRegMsg = string.Format(@"Reg|{0}|{1}", username, pwd);try{sendMsg(requestRegMsg);initLogin();}catch (Exception ex){showDialog("注册失败");return;}}#endregion#region -----------------------5. 退出/// --------------------------------------------/// /// 描述:退出/// /// /// /// --------------------------------------------private void button_Cancel_Click(object sender, EventArgs e){string msg = "Close|" + textBox_hide.Text;sendMsg(msg);Application.Exit();}#endregionpublic void addItemToComboBox(string str){//首先移除所有的列表comboBox_USER_LIST.Items.Clear();comboBox_USER_LIST.Items.Add("All");string[] strArray = str.Split('|');int i ;for ( i = 1; i < strArray.Length; i++){if (strArray[1].Equals("0")) return;comboBox_USER_LIST.Items.Add(strArray[i]);} }public void deleteItemFromComboBox(string who){comboBox_USER_LIST.Items.Remove(who);}#region -----------------------6. 定义委托,子线程中能够像消息列表中添加信息delegate void ShowMsg(string msg);delegate void AddItem(string msg);delegate void DeleteItem(string who);ShowMsg showMsg;AddItem addItem;DeleteItem deleteItem;public void DisplayMsg(string msg){try{if (this.InvokeRequired){this.Invoke(showMsg, msg);}}catch (Exception e) { }}public void addItemToList(string msg){try{if(this.InvokeRequired){this.Invoke(addItem, msg);}}catch (Exception e){}}public void removeFromToList(string who){try{if (this.InvokeRequired){this.Invoke(deleteItem, who);}}catch (Exception e) { }}private void appendMsg(string msg){textBox_CLIENT_MSG.AppendText(msg + "\n");}/// --------------------------------------------/// /// 描述:显示弹出框/// /// /// --------------------------------------------private void showDialog(string msg){MessageBox.Show(msg);}#endregion#region -----------------------8. 工具方法private bool checkInput(string username, string pwd){if (string.IsNullOrEmpty(username)){showDialog("用户名不能为空");return false;}if (string.IsNullOrEmpty(pwd)){showDialog("密码不能为空");return false;}return true;}#endregionprivate void comboBox_USER_LIST_SelectedIndexChanged(object sender, EventArgs e){}private void ClientForm_Load(object sender, EventArgs e){}}}

服务器部分代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Threading;using System.Net;using System.IO;using System.Net.Sockets;using System.Data.SqlClient;using System.Data;namespace ChatRoom.Server{public class ClientConnection{Thread threadClient = null;Socket socket = null;ServerForm serverForm = null;//在线用户的用户名集合和Socket集合public static List onlineUserName = new List();public static List onlineSocket = new List();public ClientConnection(ServerForm serverForm, Socket socket){this.serverForm = serverForm;this.socket = socket;threadClient = new Thread(watchMsg);threadClient.IsBackground = true;threadClient.Start();}#region -------------------------------------1. 实现服务器与客户端的通信private void watchMsg(){try{while (true){if (socket == null) break;byte[] byteMsgRec = new byte[1024 * 1024 * 4];int length = socket.Receive(byteMsgRec, byteMsgRec.Length, SocketFlags.None);if (length > 0){string strMsgRec = Encoding.UTF8.GetString(byteMsgRec, 0, length);handleMsg(strMsgRec);}}}catch (Exception e){ShowMsg("出现异常:" + e.Message + "\n");return;}}//服务器端向客户端发送消息public void SendMsg(string msg){try{byte[] msgSendByte = Encoding.UTF8.GetBytes(msg);socket.Send(msgSendByte);}catch (Exception ex){ShowMsg("发送消息错误:" + ex.Message + "\n");return;}}#endregion#region ----------------------------------------2. 处理转发用户消息//处理收到的请求,进行转发private void handleMsg(string msg){string[] strArray = msg.Split('|');switch (strArray[0]){case "Login":login(msg);break;case "Init":notifyAll();break;case "Reg":register(msg);break;case "Talk":talk(msg);break;case "Close":close(msg);break;default:break;}}//登录private void login(string msg){string[] strArray = msg.Split('|');string userInfo = "";for (int i = 1; i < strArray.Length; i++){userInfo += strArray[i] + "|";}userInfo = userInfo.Remove(userInfo.LastIndexOf('|'), 1);if (isLoginSucceed(userInfo)){string username = userInfo.Split('|')[0];onlineUserName.Add(username);onlineSocket.Add(this.socket);ShowMsg(username + ":加入房间" + "\n");string feedBack = "login|succeed";SendMsg(feedBack);}else{string errorMsg = "warning|登录失败";SendMsg(errorMsg);this.closeSocket();}}//注册private void register(string msg){string[] strArray = msg.Split('|');string userInfo = "";for (int i = 1; i  0){for (int i = 0; i  0 && onlineUserName.Count > 0){for (int i = 0; i < onlineSocket.Count; i++){onlineSocket[i].Send(Encoding.UTF8.GetBytes(feedBack));}}}//聊天private void talk(string msg){string[] strArray = msg.Split('|');//消息来自string fromUser = strArray[1];//消息发送给string toUser = strArray[2];string msgInfo = strArray[3];if (toUser.Equals("All"))sendToAll(fromUser, msgInfo);elsesendToUserByName(fromUser, toUser, msgInfo);}//关闭private void close(string msg){int length = onlineSocket.Count;string[] strArray = msg.Split('|');//消息来自string fromUser = strArray[1];for (int i = 0; i  0){for (int i = 0; i  0 && onlineSocket.Count > 0){for (int i = 0; i  0 && onlineUserName.Count > 0){for (int i = 0; i < onlineUserName.Count; i++){if (toUser.Equals(onlineUserName[i])){onlineSocket[i].Send(Encoding.UTF8.GetBytes(sendMsg));return;}}}}private bool isRegisterSucceed(string strInfo){StreamReader streamReader = new StreamReader("User.txt");String line = "";while ((line = streamReader.ReadLine()) != null){if (line.Equals(strInfo)) return false;}streamReader.Close();FileStream fileStream = new FileStream("User.txt", FileMode.Append);StreamWriter writer = new StreamWriter(fileStream);writer.WriteLine(strInfo);writer.Close();fileStream.Close();return true;}private bool isLoginSucceed(string userInfo)//靠文件判断的关键{StreamReader streamReader = new StreamReader("User.txt");string line = "";while ((line = streamReader.ReadLine()) != null){if (line == userInfo && !onlineUserName.Contains(userInfo.Split('|')[0]))return true;}streamReader.Close();return false; }private void closeSocket(){socket.Shutdown(SocketShutdown.Both);socket.Close();socket = null;}#endregion#region --------------------------------------2. 显示异常信息private void ShowMsg(string msg){this.serverForm.AppendMsg(msg);}#endregion}}

github源码:https://github.com/helloword22333/chat-rooms