网络编程实训报告TCP聊天程序Word下载.docx
《网络编程实训报告TCP聊天程序Word下载.docx》由会员分享,可在线阅读,更多相关《网络编程实训报告TCP聊天程序Word下载.docx(41页珍藏版)》请在冰豆网上搜索。
服务器界面如下:
客户端的登陆界面如下:
客户端的注册界面如下:
客户端的聊天窗口如下:
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()
returnbReader.ReadString();
catch(Exception)
throw;
}
UserList类
在项目中添加UserList类。
UserList类的代码如下:
publicclassUserList
publicList<
User>
list;
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("
+u.userName);
//不会给自己发送
else
foreach(Useruinlist)//如果不是新用户登陆信息,则给除自己外每个用户发送消息
publicvoidgetAllName(Useruser)
foreach(Useruinlist)
if(user==u)
continue;
getAllName,"
MainWindow代码:
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;
///<
summary>
///MainWindow.xaml的交互逻辑
/summary>
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;
client=listener.AcceptTcpClient();
//接受连接请求,连接成功
break;
//如有异常跳出侦听
UsernewUser=newUser(client);
userList.AddUser(newUser);
Receive(newUser));
publicvoidReceive(Useruser)
stringmessage=null;
message=user.Receive();
string[]split=message.Split('
switch(split[0])
case"
:
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;
if(isLeagle)//如果没登陆,添加进用户列表
user.userName=split[1];
userList.SendToAllUser(user,message);
onlineUser++;
onlineShow.Dispatcher.Invoke(()=>
onlineShow.Text="
当前在线用户数:
"
+onlineUser);
else//如果已登陆,发送sorry
sorry"
userList.RemoveUser(user);
if(isLeagle==false)//判断用户信息文本中是否有该用户,如果没有,发送sorry
register"
boolisSame=false;
string[]readUserName=ReadUserInfo();
foreach(stringuserInfoTextinreadUserName)//循环查找用户信息是否有重名
if(str[0]==split[1])
regsorry"
isSame=true;
//如果有重名,跳出循环
if(!
isSame)//循环结束没有重名可以添加进去
vara=AppDomain.CurrentDomain;
File.AppendAllText(a.BaseDirectory+@"
UserInfo.txt"
split[1]+"
"
+split[2]+"
\n"
Encoding.Default);
isregister"
talk"
stringreceiver=split[2];
if(u.userName==receiver)
u.Send(message);
user.Send(message);
logout"
onlineUser--;
+onlineUser);
getAllName"
userList.getAllName(user);
default:
privatestring[]ReadUserInfo()
//获取当前应用程序域
stringpathUserInfo=a.BaseDirectory+@"
;
//确定用户信息的文本位置
string[]readText=File.ReadAllLines(pathUserInfo,Encoding.Default);
//逐行读取文本存入数组
returnreadText;
privatevoidbtnStop_Click(objectsender,RoutedEventArgse)
userList.RemoveAllUser();
0"
listener.Stop();
btnStart.IsEnabled=true;
privatevoidWindow_Closing_1(objectsender,System.ComponentModel.CancelEventArgse)
6.2客户端
User类
namespaceClient_541307110114
publicBinaryWriterbWrite;
bWrite=newBinaryWriter(ns);
if(bReader!
=null)
if(bWrite!
bWrite.Close();
if(client!
bWrite.Write(message);
bWrite.Flush();
Login代码
usingSystem.Threading;
///Login.xaml的交互逻辑
publicpartialclassLogin:
publicUseruser;
publicboolisConnect;
publicLogin()
client=newTcpClient();
isConnect=false;
privatevoidbtnRegister_Click(objectsender,RoutedEventArgse)
if(isConnect==false)
client.Connect("
172.20.82.9"
port);
user=newUser(client);
isConnect=true;
MessageBox.Show("
连接服务器失败!
Registerreg=newRegister(user);
reg.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=="
)
请输入用户名和密码!
return;
if(isConnect==false)
Receive());
user.userName=tbUserName.Text;
SendMessage("
+user.userName+"
+password);
privatevoidSendMessage(stringmessage)
catch(Exceptionex)
发送失败!
if(isConn