网络编程实训报告TCP聊天程序.docx
- 文档编号:6421138
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:41
- 大小:1MB
网络编程实训报告TCP聊天程序.docx
《网络编程实训报告TCP聊天程序.docx》由会员分享,可在线阅读,更多相关《网络编程实训报告TCP聊天程序.docx(41页珍藏版)》请在冰豆网上搜索。
网络编程实训报告TCP聊天程序
郑州轻工业学院
实训报告
实训名称:
网络聊天程序
指导教师:
姓名:
学号:
班级:
提交日期:
1.
实训目的
通过开发一款网络聊天程序,熟练掌握多线程编程技术和TCP应用编程技术。
通过本实训,应达到如下目标:
●理解委托的概念,掌握线程之间通过委托与控件交互的方法。
●理解异常处理的机制,掌握异常处理语句的用法。
●理解线程的概念,掌握多线程编程的一般方法。
●掌握基于TCP的应用编程技术。
2.实训题目
使用C#编程语言,开发一款网络聊天程序,玩家通过客户端登陆远程的服务器,登陆成功后可以与其他在线的玩家通信,如下图所示。
3.功能描述
1.管理员可以启动停止服务器,服务器可以显示当前的在线人数。
2.玩家可以登陆服务器;登录后的玩家可以与其它在线的玩家聊天;在线玩家关闭客户端即退出登录。
3.用户可以注册账号登陆服务器,注册即可实现永久登陆。
4.需求分析
根据功能描述可知,网络聊天程序的系统结构图如下所示。
5.设计说明
服务器界面如下:
客户端的登陆界面如下:
客户端的注册界面如下:
客户端的聊天窗口如下:
6.源代码
6.1服务器端
User类
在Server_541307110114项目中添加User类。
User类的代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Net.Sockets;
usingSystem.IO;
namespaceServer_541307110114
{
publicclassUser
{
publicstringuserName;
publicTcpClientclient;
publicBinaryReaderbReader;
publicBinaryWriterbWriter;
publicUser(TcpClientclient)
{
this.client=client;
NetworkStreamns=client.GetStream();
bReader=newBinaryReader(ns);
bWriter=newBinaryWriter(ns);
}
publicvoidClose()
{
bReader.Close();
bWriter.Close();
client.Close();
}
publicvoidSend(stringmessage)
{
try
{
bWriter.Write(message);
bWriter.Flush();
}
catch(Exceptionex)
{
throwex;
}
}
publicstringReceive()
{
try
{
returnbReader.ReadString();
}
catch(Exception)
{
throw;
}
}
}
}
UserList类
在项目中添加UserList类。
UserList类的代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceServer_541307110114
{
publicclassUserList
{
publicList
publicUserList()
{
list=newList
}
publicvoidAddUser(Useruser)
{
list.Add(user);
}
publicvoidRemoveUser(Useruser)
{
user.Close();
list.Remove(user);
}
publicvoidRemoveAllUser()
{
for(inti=list.Count-1;i>=0;i--)
{
RemoveUser(list[i]);
}
}
publicvoidSendToAllUser(Useruser,stringstr)//给所有人发消息
{
string[]split=str.Split(',');//把接收的字符串分离
if(split[0]=="login")//判断是否为新登陆
{
foreach(Useruinlist)//如果为新登陆,从用户集合获取每一个登陆用户
{
u.Send(str);//给每个用户发送新用户登陆的消息
u.Send("login,"+u.userName);
if(u.userName!
=split[1])
{
user.Send("login,"+u.userName);//不会给自己发送
}
}
}
else
{
foreach(Useruinlist)//如果不是新用户登陆信息,则给除自己外每个用户发送消息
{
if(u.userName!
=split[1])
{
u.Send(str);
}
}
}
}
publicvoidgetAllName(Useruser)
{
foreach(Useruinlist)
{
if(user==u)
{
continue;
}
user.Send("getAllName,"+u.userName);
}
}
}
}
MainWindow代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Navigation;
usingSystem.Windows.Shapes;
usingSystem.Net.Sockets;
usingSystem.Net;
usingSystem.IO;
namespaceServer_541307110114
{
///
///MainWindow.xaml的交互逻辑
///
publicpartialclassMainWindow:
Window
{
publicTcpListenerlistener;
publicUserListuserList;
publicintport;
publicboolisExit;
publicintonlineUser;
publicMainWindow()
{
InitializeComponent();
port=1005;
listener=newTcpListener(IPAddress.Any,port);//绑定IP端口号用于侦听
userList=newUserList();
isExit=true;
onlineUser=0;
btnStop.IsEnabled=false;
}
privatevoidbtnStart_Click(objectsender,RoutedEventArgse)
{
listener.Start();//开始侦听
isExit=false;
Task.Run(()=>ConnectListen());//启动侦听连接线程
btnStart.IsEnabled=false;
btnStop.IsEnabled=true;
}
publicvoidConnectListen()//用于侦听来自客户端的连接请求
{
while(!
isExit)
{
TcpClientclient;
try
{
client=listener.AcceptTcpClient();//接受连接请求,连接成功
}
catch(Exception)
{
break;//如有异常跳出侦听
}
UsernewUser=newUser(client);
userList.AddUser(newUser);
Task.Run(()=>Receive(newUser));
}
}
publicvoidReceive(Useruser)
{
stringmessage=null;
while(!
isExit)
{
try
{
message=user.Receive();
}
catch(Exception)
{
}
string[]split=message.Split(',');
switch(split[0])
{
case"login":
string[]readText=ReadUserInfo();
boolisLeagle=true;
foreach(stringuserInfoTextinreadText)
{
string[]str=userInfoText.Split(',');//用逗号分隔获取到的每行用户数据
if(split[1]==str[0]&&split[2]==str[1])//将用户输入与此行的用户名密码对比,为真则登陆成功
{
foreach(UseruinuserList.list)
{
if(u.userName==split[1])//检测该用户是否已经登陆
{
isLeagle=false;
break;
}
}
if(isLeagle)//如果没登陆,添加进用户列表
{
user.userName=split[1];
userList.SendToAllUser(user,message);
onlineUser++;
onlineShow.Dispatcher.Invoke(()=>onlineShow.Text="当前在线用户数:
"+onlineUser);
break;
}
else//如果已登陆,发送sorry
{
user.Send("sorry");
userList.RemoveUser(user);
}
}
}
if(isLeagle==false)//判断用户信息文本中是否有该用户,如果没有,发送sorry
{
user.Send("sorry");
userList.RemoveUser(user);
}
break;
case"register":
boolisSame=false;
string[]readUserName=ReadUserInfo();
foreach(stringuserInfoTextinreadUserName)//循环查找用户信息是否有重名
{
string[]str=userInfoText.Split(',');
if(str[0]==split[1])
{
user.Send("regsorry");
isSame=true;
break;//如果有重名,跳出循环
}
else
{
continue;
}
}
if(!
isSame)//循环结束没有重名可以添加进去
{
vara=AppDomain.CurrentDomain;
File.AppendAllText(a.BaseDirectory+@"UserInfo.txt",split[1]+","+split[2]+"\n",Encoding.Default);
user.Send("isregister");
}
break;
case"talk":
stringreceiver=split[2];
foreach(UseruinuserList.list)
{
if(u.userName==receiver)
{
u.Send(message);
}
}
user.Send(message);
break;
case"logout":
userList.SendToAllUser(user,message);
userList.RemoveUser(user);
onlineUser--;
onlineShow.Dispatcher.Invoke(()=>onlineShow.Text="当前在线用户数:
"+onlineUser);
break;
case"getAllName":
userList.getAllName(user);
break;
default:
break;
}
}
}
privatestring[]ReadUserInfo()
{
vara=AppDomain.CurrentDomain;//获取当前应用程序域
stringpathUserInfo=a.BaseDirectory+@"UserInfo.txt";//确定用户信息的文本位置
string[]readText=File.ReadAllLines(pathUserInfo,Encoding.Default);//逐行读取文本存入数组
returnreadText;
}
privatevoidbtnStop_Click(objectsender,RoutedEventArgse)
{
userList.RemoveAllUser();
onlineShow.Dispatcher.Invoke(()=>onlineShow.Text="当前在线用户数:
0");
isExit=true;
listener.Stop();
btnStart.IsEnabled=true;
btnStop.IsEnabled=false;
}
privatevoidWindow_Closing_1(objectsender,System.ComponentModel.CancelEventArgse)
{
userList.RemoveAllUser();
isExit=true;
listener.Stop();
}
}
}
6.2客户端
User类
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Net.Sockets;
usingSystem.IO;
namespaceClient_541307110114
{
publicclassUser
{
publicstringuserName;
publicTcpClientclient;
publicBinaryReaderbReader;
publicBinaryWriterbWrite;
publicUser(TcpClientclient)
{
this.client=client;
NetworkStreamns=client.GetStream();
bReader=newBinaryReader(ns);
bWrite=newBinaryWriter(ns);
}
publicvoidClose()
{
if(bReader!
=null)
{
bReader.Close();
}
if(bWrite!
=null)
{
bWrite.Close();
}
if(client!
=null)
{
client.Close();
}
}
publicvoidSend(stringmessage)
{
try
{
bWrite.Write(message);
bWrite.Flush();
}
catch(Exceptionex)
{
throwex;
}
}
publicstringReceive()
{
try
{
returnbReader.ReadString();
}
catch(Exception)
{
throw;
}
}
}
}
Login代码
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Shapes;
usingSystem.Net.Sockets;
usingSystem.Threading;
namespaceClient_541307110114
{
///
///Login.xaml的交互逻辑
///
publicpartialclassLogin:
Window
{
publicUseruser;
publicintport;
publicboolisConnect;
publicTcpClientclient;
publicLogin()
{
InitializeComponent();
client=newTcpClient();
port=1005;
isConnect=false;
}
privatevoidbtnRegister_Click(objectsender,RoutedEventArgse)
{
try
{
if(isConnect==false)
{
try
{
client.Connect("172.20.82.9",port);
user=newUser(client);
isConnect=true;
}
catch(Exception)
{
MessageBox.Show("连接服务器失败!
");
}
}
Registerreg=newRegister(user);
reg.Show();
}
catch(Exceptionex)
{
MessageBox.Show("连接失败!
"+ex);
}
}
privatevoidbtnLogin_Click(objectsender,RoutedEventArgse)
{
//使用一个IntPtr类型值来存储加密字符串的起始点
IntPtrp=System.Runtime.InteropServices.Marshal.SecureStringToBSTR(this.tbUserPassword.SecurePassword);
//使用.NET内部算法把IntPtr指向处的字符集合转换成字符串
stringpassword=System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p);
if(tbUserName.Text==""||password=="")
{
MessageBox.Show("请输入用户名和密码!
");
return;
}
try
{
if(isConnect==false)
{
try
{
client.Connect("172.20.82.9",port);
user=newUser(client);
isConnect=true;
}
catch(Exception)
{
MessageBox.Show("连接服务器失败!
");
}
}
Task.Run(()=>Receive());
user.userName=tbUserName.Text;
SendMessage("login,"+user.userName+","+password);
}
catch(Exception)
{
MessageBox.Show("连接失败!
");
}
}
privatevoidSendMessage(stringmessage)
{
try
{
user.Send(message);
}
catch(Exceptionex)
{
isConnect=false;
MessageBox.Show("发送失败!
"+ex);
}
}
privatevoidWindow_Closing_1(objectsender,System.ComponentModel.CancelEventArgse)
{
if(isConn
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程 报告 TCP 聊天 程序