小言_互联网的博客

大二课设-基于Tcp的c/s模式的网络聊天室(c#)

371人阅读  评论(0)

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

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

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

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

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

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

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

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

 

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

 

 

客户端

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

 服务端

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

 

用户数据存储方式

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

 源码:

客户端部分:


  
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. using System.Threading;
  11. using System.Net.Sockets;
  12. using System.Net;
  13. using Newtonsoft.Json;
  14. namespace ChatRoom.Client
  15. {
  16. public partial class ClientForm : Form
  17. {
  18. //string rs;
  19. public ClientForm()
  20. {
  21. showMsg = new ShowMsg(appendMsg);
  22. addItem = new AddItem(addItemToComboBox);
  23. deleteItem = new DeleteItem(deleteItemFromComboBox);
  24. InitializeComponent();
  25. }
  26. #region -----------------------1. Socket处理
  27. IPAddress address = null;
  28. Socket clientSocket = null;
  29. IPEndPoint endPoint = null;
  30. private void connecToServer()
  31. {
  32. try
  33. {
  34. //创建客户端套接字
  35. clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  36. address = IPAddress.Parse( "127.0.0.1");
  37. endPoint = new IPEndPoint(address, 9000);
  38. //连接服务器
  39. clientSocket.Connect(endPoint);
  40. }
  41. catch (Exception e)
  42. {
  43. string errStr = string.Format( "系统提示:出现了错误!\r\n错误信息:{0}\r\n", e.Message);
  44. textBox_CLIENT_MSG.AppendText(errStr);
  45. return;
  46. }
  47. }
  48. /// <summary>
  49. /// 获取服务器发送过来的数据
  50. /// </summary>
  51. private string recvMsg()
  52. {
  53. try
  54. {
  55. byte[] receveMsg = new byte[ 1024 * 1024 * 2];
  56. int length = clientSocket.Receive(receveMsg);
  57. return Encoding.UTF8.GetString(receveMsg, 0, length);
  58. }
  59. catch (Exception e)
  60. {
  61. return e.Message;
  62. }
  63. }
  64. /// <summary>
  65. /// 描述:发送数据到服务器进行处理
  66. /// </summary>
  67. /// <param name="msg"></param>
  68. private void sendMsg(string msg)
  69. {
  70. try
  71. {
  72. clientSocket.Send(Encoding.UTF8.GetBytes(msg));
  73. }
  74. catch (Exception ex)
  75. {
  76. showDialog( "Error:"+ex.Message);
  77. }
  78. }
  79. #endregion
  80. #region -----------------------2. 发送消息
  81. /// --------------------------------------------
  82. /// <summary>
  83. /// 描述:发送消息
  84. /// </summary>
  85. /// <param name="sender"></param>
  86. /// <param name="e"></param>
  87. /// --------------------------------------------
  88. private void button_SEND_Click(object sender, EventArgs e)
  89. {
  90. try
  91. {
  92. //连接服务器成功发送消息
  93. string msg = textBox_CLIENT_SEND_MSG.Text.ToString();
  94. string logininUser = textBox_hide.Text;
  95. if ( string.IsNullOrEmpty(logininUser))
  96. {
  97. showDialog( "您还没登录");
  98. return;
  99. }
  100. if ( string.IsNullOrEmpty(msg))
  101. {
  102. showDialog( "发送内容不能为空");
  103. return;
  104. }
  105. string toUser = comboBox_USER_LIST.Text.ToString();
  106. if ( string.IsNullOrEmpty(toUser))
  107. {
  108. showDialog( "请选择发送对象!");
  109. return;
  110. }
  111. string sendStrMsg = "Talk|" + textBox_hide.Text.ToString() + "|" + toUser + "|" + msg;
  112. sendMsg(sendStrMsg);
  113. // sendMsg(rs);
  114. textBox_CLIENT_SEND_MSG.Text = "";
  115. textBox_CLIENT_MSG.AppendText( "\r\n"+ "你对" + toUser + "说:" + msg + "\r\n");
  116. }
  117. catch (Exception ex)
  118. {
  119. //出现异常,如:没有连接到服务器
  120. string errorMsg = string.Format( @"发送失败:{0}", ex.Message);
  121. textBox_CLIENT_MSG.AppendText(errorMsg + "\r\n");
  122. }
  123. }
  124. #endregion
  125. #region -----------------------3. 登录
  126. /// --------------------------------------------
  127. /// <summary>
  128. /// 描述:登录
  129. /// </summary>
  130. /// <param name="sender"></param>
  131. /// <param name="e"></param>
  132. /// --------------------------------------------
  133. private void button_Login_Click(object sender, EventArgs e)
  134. {
  135. string username = textBox_UserName.Text.ToString();
  136. string pwd = textBox_Pwd.Text.ToString();
  137. if (!checkInput(username, pwd)) return;
  138. connecToServer();
  139. string requestLoginMsg = string.Format( @"Login|{0}|{1}", username, pwd);
  140. try
  141. {
  142. sendMsg(requestLoginMsg);
  143. //初始化登录
  144. initLogin();
  145. }
  146. catch (Exception ex)
  147. {
  148. showDialog( "登录失败");
  149. return;
  150. }
  151. }
  152. private void initLogin()
  153. {
  154. string strRecvMsg = recvMsg();
  155. string[] strArray = strRecvMsg.Split( '|');
  156. switch (strArray[ 0])
  157. {
  158. case "login":
  159. if (strArray[ 1].Equals( "succeed"))
  160. {
  161. string user = textBox_UserName.Text;
  162. button_Login.Dispose();
  163. button_Register.Dispose();
  164. textBox_Pwd.Dispose();
  165. textBox_UserName.Dispose();
  166. label2.Dispose();
  167. label3.Dispose();
  168. label_hide.Show();
  169. textBox_hide.Text = user;
  170. textBox_hide.Show();
  171. //启动客户端与服务器的连接服务
  172. new ClientService(clientSocket, this);
  173. string strSendMsg = "Init|online";
  174. sendMsg(strSendMsg);
  175. }
  176. break;
  177. case "warning":
  178. string warningMsg = this.recvMsg();
  179. showDialog(warningMsg.Split( '|')[ 1]);
  180. clientSocket.Shutdown(SocketShutdown.Both);
  181. clientSocket.Close();
  182. clientSocket = null;
  183. break;
  184. }
  185. }
  186. #endregion
  187. #region -----------------------4. 注册
  188. /// --------------------------------------------
  189. /// <summary>
  190. /// 描述:注册
  191. /// </summary>
  192. /// <param name="sender"></param>
  193. /// <param name="e"></param>
  194. /// --------------------------------------------
  195. private void button_Register_Click(object sender, EventArgs e)
  196. {
  197. string username = textBox_UserName.Text.ToString();
  198. string pwd = textBox_Pwd.Text.ToString();
  199. if (!checkInput(username, pwd)) return;
  200. connecToServer();
  201. string requestRegMsg = string.Format( @"Reg|{0}|{1}", username, pwd);
  202. try
  203. {
  204. sendMsg(requestRegMsg);
  205. initLogin();
  206. }
  207. catch (Exception ex)
  208. {
  209. showDialog( "注册失败");
  210. return;
  211. }
  212. }
  213. #endregion
  214. #region -----------------------5. 退出
  215. /// --------------------------------------------
  216. /// <summary>
  217. /// 描述:退出
  218. /// </summary>
  219. /// <param name="sender"></param>
  220. /// <param name="e"></param>
  221. /// --------------------------------------------
  222. private void button_Cancel_Click(object sender, EventArgs e)
  223. {
  224. string msg = "Close|" + textBox_hide.Text;
  225. sendMsg(msg);
  226. Application.Exit();
  227. }
  228. #endregion
  229. public void addItemToComboBox(string str)
  230. {
  231. //首先移除所有的列表
  232. comboBox_USER_LIST.Items.Clear();
  233. comboBox_USER_LIST.Items.Add( "All");
  234. string[] strArray = str.Split( '|');
  235. int i ;
  236. for ( i = 1; i < strArray.Length; i++)
  237. {
  238. if (strArray[ 1].Equals( "0")) return;
  239. comboBox_USER_LIST.Items.Add(strArray[i]);
  240. }
  241. }
  242. public void deleteItemFromComboBox(string who)
  243. {
  244. comboBox_USER_LIST.Items.Remove(who);
  245. }
  246. #region -----------------------6. 定义委托,子线程中能够像消息列表中添加信息
  247. delegate void ShowMsg(string msg);
  248. delegate void AddItem(string msg);
  249. delegate void DeleteItem(string who);
  250. ShowMsg showMsg;
  251. AddItem addItem;
  252. DeleteItem deleteItem;
  253. public void DisplayMsg(string msg)
  254. {
  255. try
  256. {
  257. if ( this.InvokeRequired)
  258. {
  259. this.Invoke(showMsg, msg);
  260. }
  261. }
  262. catch (Exception e) { }
  263. }
  264. public void addItemToList(string msg)
  265. {
  266. try
  267. {
  268. if( this.InvokeRequired)
  269. {
  270. this.Invoke(addItem, msg);
  271. }
  272. }
  273. catch (Exception e)
  274. {}
  275. }
  276. public void removeFromToList(string who)
  277. {
  278. try
  279. {
  280. if ( this.InvokeRequired)
  281. {
  282. this.Invoke(deleteItem, who);
  283. }
  284. }
  285. catch (Exception e) { }
  286. }
  287. private void appendMsg(string msg)
  288. {
  289. textBox_CLIENT_MSG.AppendText(msg + "\n");
  290. }
  291. /// --------------------------------------------
  292. /// <summary>
  293. /// 描述:显示弹出框
  294. /// </summary>
  295. /// <param name="msg"></param>
  296. /// --------------------------------------------
  297. private void showDialog(string msg)
  298. {
  299. MessageBox.Show(msg);
  300. }
  301. #endregion
  302. #region -----------------------8. 工具方法
  303. private bool checkInput(string username, string pwd)
  304. {
  305. if ( string.IsNullOrEmpty(username))
  306. {
  307. showDialog( "用户名不能为空");
  308. return false;
  309. }
  310. if ( string.IsNullOrEmpty(pwd))
  311. {
  312. showDialog( "密码不能为空");
  313. return false;
  314. }
  315. return true;
  316. }
  317. #endregion
  318. private void comboBox_USER_LIST_SelectedIndexChanged(object sender, EventArgs e)
  319. {
  320. }
  321. private void ClientForm_Load(object sender, EventArgs e)
  322. {
  323. }
  324. }
  325. }

服务器部分代码:


  
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Threading;
  7. using System.Net;
  8. using System.IO;
  9. using System.Net.Sockets;
  10. using System.Data.SqlClient;
  11. using System.Data;
  12. namespace ChatRoom.Server
  13. {
  14. public class ClientConnection
  15. {
  16. Thread threadClient = null;
  17. Socket socket = null;
  18. ServerForm serverForm = null;
  19. //在线用户的用户名集合和Socket集合
  20. public static List< string> onlineUserName = new List< string>();
  21. public static List<Socket> onlineSocket = new List<Socket>();
  22. public ClientConnection(ServerForm serverForm, Socket socket)
  23. {
  24. this.serverForm = serverForm;
  25. this.socket = socket;
  26. threadClient = new Thread(watchMsg);
  27. threadClient.IsBackground = true;
  28. threadClient.Start();
  29. }
  30. #region -------------------------------------1. 实现服务器与客户端的通信
  31. private void watchMsg()
  32. {
  33. try
  34. {
  35. while ( true)
  36. {
  37. if (socket == null) break;
  38. byte[] byteMsgRec = new byte[ 1024 * 1024 * 4];
  39. int length = socket.Receive(byteMsgRec, byteMsgRec.Length, SocketFlags.None);
  40. if (length > 0)
  41. {
  42. string strMsgRec = Encoding.UTF8.GetString(byteMsgRec, 0, length);
  43. handleMsg(strMsgRec);
  44. }
  45. }
  46. }
  47. catch (Exception e)
  48. {
  49. ShowMsg( "出现异常:" + e.Message + "\n");
  50. return;
  51. }
  52. }
  53. //服务器端向客户端发送消息
  54. public void SendMsg(string msg)
  55. {
  56. try
  57. {
  58. byte[] msgSendByte = Encoding.UTF8.GetBytes(msg);
  59. socket.Send(msgSendByte);
  60. }
  61. catch (Exception ex)
  62. {
  63. ShowMsg( "发送消息错误:" + ex.Message + "\n");
  64. return;
  65. }
  66. }
  67. #endregion
  68. #region ----------------------------------------2. 处理转发用户消息
  69. //处理收到的请求,进行转发
  70. private void handleMsg(string msg)
  71. {
  72. string[] strArray = msg.Split( '|');
  73. switch (strArray[ 0])
  74. {
  75. case "Login":
  76. login(msg);
  77. break;
  78. case "Init":
  79. notifyAll();
  80. break;
  81. case "Reg":
  82. register(msg);
  83. break;
  84. case "Talk":
  85. talk(msg);
  86. break;
  87. case "Close":
  88. close(msg);
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. //登录
  95. private void login(string msg)
  96. {
  97. string[] strArray = msg.Split( '|');
  98. string userInfo = "";
  99. for ( int i = 1; i < strArray.Length; i++)
  100. {
  101. userInfo += strArray[i] + "|";
  102. }
  103. userInfo = userInfo.Remove(userInfo.LastIndexOf( '|'), 1);
  104. if (isLoginSucceed(userInfo))
  105. {
  106. string username = userInfo.Split( '|')[ 0];
  107. onlineUserName.Add(username);
  108. onlineSocket.Add( this.socket);
  109. ShowMsg(username + ":加入房间" + "\n");
  110. string feedBack = "login|succeed";
  111. SendMsg(feedBack);
  112. }
  113. else
  114. {
  115. string errorMsg = "warning|登录失败";
  116. SendMsg(errorMsg);
  117. this.closeSocket();
  118. }
  119. }
  120. //注册
  121. private void register(string msg)
  122. {
  123. string[] strArray = msg.Split( '|');
  124. string userInfo = "";
  125. for ( int i = 1; i < strArray.Length; i++)
  126. {
  127. userInfo += strArray[i] + "|";
  128. }
  129. userInfo = userInfo.Remove(userInfo.LastIndexOf( '|'), 1);
  130. if (isRegisterSucceed(userInfo))
  131. {
  132. string username = userInfo.Split( '|')[ 0];
  133. onlineUserName.Add(username);
  134. onlineSocket.Add( this.socket);
  135. ShowMsg(username + ":加入房间" + "\n");
  136. string feedBack = "login|succeed";
  137. SendMsg(feedBack);
  138. }
  139. else
  140. {
  141. string feedBack = string.Format( @"warning|登录失败!");
  142. SendMsg(feedBack);
  143. this.closeSocket();
  144. }
  145. }
  146. //请求在线用户
  147. private void notifyAll()
  148. {
  149. string feedBack = "online";
  150. if (onlineUserName.Count > 0)
  151. {
  152. for ( int i = 0; i < onlineUserName.Count; i++)
  153. {
  154. feedBack += "|" + onlineUserName[i];
  155. }
  156. }
  157. else
  158. {
  159. feedBack += "|0";
  160. }
  161. if (onlineSocket.Count > 0 && onlineUserName.Count > 0)
  162. {
  163. for ( int i = 0; i < onlineSocket.Count; i++)
  164. {
  165. onlineSocket[i].Send(Encoding.UTF8.GetBytes(feedBack));
  166. }
  167. }
  168. }
  169. //聊天
  170. private void talk(string msg)
  171. {
  172. string[] strArray = msg.Split( '|');
  173. //消息来自
  174. string fromUser = strArray[ 1];
  175. //消息发送给
  176. string toUser = strArray[ 2];
  177. string msgInfo = strArray[ 3];
  178. if (toUser.Equals( "All"))
  179. sendToAll(fromUser, msgInfo);
  180. else
  181. sendToUserByName(fromUser, toUser, msgInfo);
  182. }
  183. //关闭
  184. private void close(string msg)
  185. {
  186. int length = onlineSocket.Count;
  187. string[] strArray = msg.Split( '|');
  188. //消息来自
  189. string fromUser = strArray[ 1];
  190. for ( int i = 0; i < length; i++)
  191. {
  192. if (fromUser.Equals(onlineUserName[i]))
  193. {
  194. onlineUserName.Remove(fromUser);
  195. Socket scoket = onlineSocket[i];
  196. onlineSocket.Remove(scoket);
  197. break;
  198. }
  199. }
  200. socket.Shutdown(SocketShutdown.Both);
  201. socket.Close();
  202. socket = null;
  203. ShowMsg( "提示:"+fromUser+ "离开聊天室");
  204. length = onlineSocket.Count;
  205. if (onlineSocket.Count > 0)
  206. {
  207. for ( int i = 0; i < length; i++)
  208. {
  209. string sendMsg = string.Format( @"Close|{0}", fromUser);
  210. onlineSocket[i].Send(Encoding.UTF8.GetBytes(sendMsg));
  211. }
  212. }
  213. }
  214. private void sendToAll(string fromUser, string msg)
  215. {
  216. if (onlineUserName.Count > 0 && onlineSocket.Count > 0)
  217. {
  218. for ( int i = 0; i < onlineSocket.Count; i++)
  219. {
  220. string sendMsg = string.Format( "talk|{0}:{1}", fromUser, msg);
  221. onlineSocket[i].Send(Encoding.UTF8.GetBytes(sendMsg));
  222. }
  223. }
  224. }
  225. private void sendToUserByName(string fromUser, string toUser, string msg)
  226. {
  227. string sendMsg = string.Format( @"talk|{0}:{1}", fromUser, msg);
  228. if (onlineSocket.Count > 0 && onlineUserName.Count > 0)
  229. {
  230. for ( int i = 0; i < onlineUserName.Count; i++)
  231. {
  232. if (toUser.Equals(onlineUserName[i]))
  233. {
  234. onlineSocket[i].Send(Encoding.UTF8.GetBytes(sendMsg));
  235. return;
  236. }
  237. }
  238. }
  239. }
  240. private bool isRegisterSucceed(string strInfo)
  241. {
  242. StreamReader streamReader = new StreamReader( "User.txt");
  243. String line = "";
  244. while ((line = streamReader.ReadLine()) != null)
  245. {
  246. if (line.Equals(strInfo)) return false;
  247. }
  248. streamReader.Close();
  249. FileStream fileStream = new FileStream( "User.txt", FileMode.Append);
  250. StreamWriter writer = new StreamWriter(fileStream);
  251. writer.WriteLine(strInfo);
  252. writer.Close();
  253. fileStream.Close();
  254. return true;
  255. }
  256. private bool isLoginSucceed(string userInfo)//靠文件判断的关键
  257. {
  258. StreamReader streamReader = new StreamReader( "User.txt");
  259. string line = "";
  260. while ((line = streamReader.ReadLine()) != null)
  261. {
  262. if (line == userInfo && !onlineUserName.Contains(userInfo.Split( '|')[ 0]))
  263. return true;
  264. }
  265. streamReader.Close();
  266. return false;
  267. }
  268. private void closeSocket()
  269. {
  270. socket.Shutdown(SocketShutdown.Both);
  271. socket.Close();
  272. socket = null;
  273. }
  274. #endregion
  275. #region --------------------------------------2. 显示异常信息
  276. private void ShowMsg(string msg)
  277. {
  278. this.serverForm.AppendMsg(msg);
  279. }
  280. #endregion
  281. }
  282. }

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


转载:https://blog.csdn.net/m0_53394907/article/details/125375792
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场