设计一个网络聊天室,能够显示有关该系统基本信息的描述,如:客户端的实例信息、在线等,具体要求如下:
(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();
-
}
-
#endregion
-
-
public 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;
-
}
-
#endregion
-
-
private 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);
-
else
-
sendToUserByName(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
转载:https://blog.csdn.net/m0_53394907/article/details/125375792