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

(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;}}/// <summary>/// 获取服务器发送过来的数据/// </summary>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;}}/// <summary>/// 描述:发送数据到服务器进行处理/// </summary>/// <param name="msg"></param>private void sendMsg(string msg){try{clientSocket.Send(Encoding.UTF8.GetBytes(msg));}catch (Exception ex){showDialog("Error:"+ex.Message);}}#endregion #region -----------------------2. 发送消息/// --------------------------------------------/// <summary>/// 描述:发送消息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// --------------------------------------------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. 登录/// --------------------------------------------/// <summary>/// 描述:登录/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// --------------------------------------------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. 注册/// --------------------------------------------/// <summary>/// 描述:注册/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// --------------------------------------------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. 退出/// --------------------------------------------/// <summary>/// 描述:退出/// </summary>/// <param name="sender"></param>/// <param name="e"></param>/// --------------------------------------------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");}/// --------------------------------------------/// <summary>/// 描述:显示弹出框/// </summary>/// <param name="msg"></param>/// --------------------------------------------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<string> onlineUserName = new List<string>();public static List<Socket> onlineSocket = new List<Socket>();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 < strArray.Length; i++){userInfo += strArray[i] + "|";}userInfo = userInfo.Remove(userInfo.LastIndexOf('|'), 1);if (isRegisterSucceed(userInfo)){string username = userInfo.Split('|')[0];onlineUserName.Add(username);onlineSocket.Add(this.socket);ShowMsg(username + ":加入房间" + "\n");string feedBack = "login|succeed";SendMsg(feedBack);}else{string feedBack = string.Format(@"warning|登录失败!");SendMsg(feedBack);this.closeSocket();}}//请求在线用户private void notifyAll(){string feedBack = "online";if (onlineUserName.Count > 0){for (int i = 0; i < onlineUserName.Count; i++){feedBack += "|" + onlineUserName[i];}}else{feedBack += "|0";}if (onlineSocket.Count > 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 < length; i++){if (fromUser.Equals(onlineUserName[i])){onlineUserName.Remove(fromUser);Socket scoket = onlineSocket[i];onlineSocket.Remove(scoket);break;}}socket.Shutdown(SocketShutdown.Both);socket.Close();socket = null;ShowMsg("提示:"+fromUser+"离开聊天室");length = onlineSocket.Count;if (onlineSocket.Count > 0){for (int i = 0; i < length; i++){string sendMsg = string.Format(@"Close|{0}", fromUser);onlineSocket[i].Send(Encoding.UTF8.GetBytes(sendMsg));}}}private void sendToAll(string fromUser, string msg){if (onlineUserName.Count > 0 && onlineSocket.Count > 0){for (int i = 0; i < onlineSocket.Count; i++){string sendMsg = string.Format("talk|{0}:{1}", fromUser, msg);onlineSocket[i].Send(Encoding.UTF8.GetBytes(sendMsg));}}}private void sendToUserByName(string fromUser, string toUser, string msg){string sendMsg = string.Format(@"talk|{0}:{1}", fromUser, msg);if (onlineSocket.Count > 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

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

  1. linux点对点聊天室的实现与设计心得,基于Socket接口的Linux与Windows网络聊天室设计与实现...

    陈洁 孟晓景 摘要:为了实现Linux与Windows跨平台通信,及时共享信息,构建了一个适用于跨平台的网络聊天室通信程序.先搭建跨平台通信环境,然后使用Socket套接字网络编程接口实现通信.整个系 ...

  2. 简易的学生社团管理(大二课设)

    //STUDENT.h//STUDENT.h #ifndef STUDENT_H_INCLUDED #define STUDENT_H_INCLUDED#include<stdio.h> ...

  3. 大二课设,采用 bootstrap + express + mysql 实现电影售票系统(附带源码)

    文章目录 前端 1. 主页模块 2. 用户管理模块 3. 用户个人中心页面 4. 管理员页面 后端 1. 数据库处理 2. 后台自动发送验证邮箱 3. 用于产生六位随机验证码 4. 管理员路由设置 5 ...

  4. 【网络聊天室】——基于socket编程的TCP/UDP网络聊天服务器

    早期网络刚刚普及的时候,给人们印象最深的就是上网聊天,虽然作为一名上世纪的尾巴刚刚出生的我没有经历过,但仍从有所耳闻,那个时期是网络聊天室风靡的年代,全国知名聊天室大家都争破头的想要进去,基于如上和一 ...

  5. 基于TCP的网络聊天室实现(C语言)

    基于TCP的网络聊天室实现(C语言) 一.网络聊天室的功能 二.网络聊天室的结果展示 三.实现思路及流程 四.代码及说明 1.LinkList.h 2.LinkList.c 3.client.c 4. ...

  6. 基于TCP协议的网络聊天室

    创建服务端程序 public class Server {public static void main(String[] args) {new Thread(new ServerTask()).st ...

  7. 基于Java socket的网络聊天室的设计与实现

    目 录 摘要 I Abstract II 目 录 III 1 引言 1 2 网络聊天室的简介 2 2.1网络聊天室现状和发展 2 3 完成网络聊天室的技术以及环境 4 3.1 Java的介绍 4 3. ...

  8. [源码和文档分享]基于java语言的C/S模式网络聊天室软件

    一 需求分析 采用C/S模式,基于TCP协议编程的方式,使得各个用户通过服务器转发实现聊天的功能 分为三大模块:客户端模块.服务器端模块和公共辅助类模块 客户端模块的主要功能: 登陆功能:用户可以注册 ...

  9. 基于.NET SingalR,LayIM2.0实现的web聊天室

    LayIM官网 http://www.layui.com/doc/layim.html 博客教程:http://www.cnblogs.com/panzi/p/5767095.html 项目说明:基于 ...

最新文章

  1. Nginx reload的时候出现的问题/usr/local/nginx/logs/nginx.pid
  2. 健康管理-健康管理特点
  3. sql server express 并发数的限制_阿里数据库性能诊断的利器——SQL执行干预
  4. JEP 181不兼容,嵌套类/ 2
  5. 云谊网-赴日人才社交网络
  6. matlab中的uint8函数,未定义与 'uint8' 类型的输入参数相对应的函数 'fitnessty'
  7. 二级mysql教程下载_全国计算机等级考试教程:二级MySQL数据库程序设计
  8. scala trait
  9. Keras 中的循环神经网络 (RNN)
  10. 十大注意事项 防止系统重装时遭遇病毒
  11. dd命令打包多个文件_Android shell 下dd命令浅析
  12. Python的三种基本数据类型
  13. 小米air2se耳机只有一边有声音怎么办_别光盯着AirPods,这些无线蓝牙耳机,其实也很好用...
  14. 初装Windows11无法打开Windows安全中心主界面
  15. 电信笔试C语言,2021中国电信考试试题附答案(12)
  16. DB2 表字段值变更记录
  17. Django项目使用NGINX通过LDAP实现用户验证
  18. u检验中的查u界值表_统计学中,知道u值,如何确定P值,是通过查表吗
  19. Springboot 自定义全局异常处理
  20. win7下 EPLAN新建项目出现“一个内部错误”的解决方法

热门文章

  1. 27、extjs操作用友华表Cell之合并单元格
  2. 3ds max biped 缩放教程
  3. 7805扩流电路(转)
  4. 《中间件》——kafka的工作原理解析
  5. Java数据结构——数组、链表
  6. windows模拟键盘鼠标事件DirectX游戏中
  7. 新疆理化所计算机复试科目,中科院新疆理化技术研究所
  8. aerospike_install_sql
  9. 老生常谈:微博,QQ,淘宝三种开放平台对比
  10. Web Service(三):先了解SOA