网络编程实训报告-TCP聊天程序.docx_第1页
网络编程实训报告-TCP聊天程序.docx_第2页
网络编程实训报告-TCP聊天程序.docx_第3页
网络编程实训报告-TCP聊天程序.docx_第4页
网络编程实训报告-TCP聊天程序.docx_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

郑州轻工业学院实训报告实训名称:网络聊天程序指导教师:姓名:学号:班级:提交日期:1. 实训目的通过开发一款网络聊天程序,熟练掌握多线程编程技术和TCP应用编程技术。通过本实训,应达到如下目标:l 理解委托的概念,掌握线程之间通过委托与控件交互的方法。l 理解异常处理的机制,掌握异常处理语句的用法。l 理解线程的概念,掌握多线程编程的一般方法。l 掌握基于TCP的应用编程技术。2. 实训题目使用C#编程语言,开发一款网络聊天程序,玩家通过客户端登陆远程的服务器,登陆成功后可以与其他在线的玩家通信,如下图所示。3. 功能描述1. 管理员可以启动停止服务器,服务器可以显示当前的在线人数。2. 玩家可以登陆服务器;登录后的玩家可以与其它在线的玩家聊天;在线玩家关闭客户端即退出登录。3. 用户可以注册账号登陆服务器,注册即可实现永久登陆。4. 需求分析根据功能描述可知,网络聊天程序的系统结构图如下所示。玩家客户端用户用户接口服务器端用户集合通信接口管理员用户接口5. 设计说明服务器界面如下:客户端的登陆界面如下:客户端的注册界面如下:客户端的聊天窗口如下:6. 源代码6.1服务器端 User类在Server_541307110114项目中添加User类。User类的代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Net.Sockets;using System.IO;namespace Server_541307110114 public class User public string userName; public TcpClient client; public BinaryReader bReader; public BinaryWriter bWriter; public User(TcpClient client) this.client = client; NetworkStream ns = client.GetStream(); bReader = new BinaryReader(ns); bWriter = new BinaryWriter(ns); public void Close() bReader.Close(); bWriter.Close(); client.Close(); public void Send(string message) try bWriter.Write(message); bWriter.Flush(); catch (Exception ex) throw ex; public string Receive() try return bReader.ReadString(); catch (Exception) throw; UserList类在项目中添加UserList类。UserList类的代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Server_541307110114 public class UserList public List list; public UserList() list=new List(); public void AddUser(User user) list.Add(user); public void RemoveUser(User user) user.Close(); list.Remove(user); public void RemoveAllUser() for (int i = list.Count-1; i = 0; i-) RemoveUser(listi); public void SendToAllUser(User user, string str)/给所有人发消息 string split = str.Split(,);/把接收的字符串分离 if (split0=login)/判断是否为新登陆 foreach (User u in list)/如果为新登陆,从用户集合获取每一个登陆用户 u.Send(str);/给每个用户发送新用户登陆的消息 u.Send(login,+u.userName); if (u.userName!=split1) user.Send(login, + u.userName);/不会给自己发送 else foreach (User u in list)/如果不是新用户登陆信息,则给除自己外每个用户发送消息 if (u.userName!=split1) u.Send(str); public void getAllName(User user) foreach (User u in list) if (user = u) continue; user.Send(getAllName, + u.userName); MainWindow代码:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using System.Net.Sockets;using System.Net;using System.IO;namespace Server_541307110114 / / MainWindow.xaml 的交互逻辑 / public partial class MainWindow : Window public TcpListener listener; public UserList userList; public int port; public bool isExit; public int onlineUser; public MainWindow() InitializeComponent(); port = 1005; listener = new TcpListener(IPAddress.Any,port);/绑定IP端口号用于侦听 userList = new UserList(); isExit = true; onlineUser = 0; btnStop.IsEnabled = false; private void btnStart_Click(object sender, RoutedEventArgs e) listener.Start();/开始侦听 isExit = false; Task.Run() = ConnectListen();/启动侦听连接线程 btnStart.IsEnabled = false; btnStop.IsEnabled = true; public void ConnectListen()/用于侦听来自客户端的连接请求 while (!isExit) TcpClient client; try client = listener.AcceptTcpClient();/接受连接请求,连接成功 catch (Exception) break;/如有异常跳出侦听 User newUser = new User(client); userList.AddUser(newUser); Task.Run() = Receive(newUser); public void Receive(User user) string message = null; while (!isExit) try message = user.Receive(); catch (Exception) string split = message.Split(,); switch (split0) case login: string readText = ReadUserInfo(); bool isLeagle = true; foreach (string userInfoText in readText) string str = userInfoText.Split(,);/用逗号分隔获取到的每行用户数据 if (split1=str0&split2=str1)/将用户输入与此行的用户名密码对比,为真则登陆成功 foreach (User u in userList.list) if (u.userName=split1)/检测该用户是否已经登陆 isLeagle = false; break; if (isLeagle)/如果没登陆,添加进用户列表 user.userName = split1; 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: bool isSame = false; string readUserName = ReadUserInfo(); foreach (string userInfoText in readUserName)/循环查找用户信息是否有重名 string str = userInfoText.Split(,); if (str0=split1) user.Send(regsorry); isSame = true; break;/如果有重名,跳出循环 else continue; if (!isSame)/循环结束没有重名可以添加进去 var a = AppDomain.CurrentDomain; File.AppendAllText(a.BaseDirectory + UserInfo.txt, split1 + , + split2 + n, Encoding.Default); user.Send(isregister); break; case talk: string receiver = split2; foreach (User u in userList.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; private string ReadUserInfo() var a = AppDomain.CurrentDomain;/获取当前应用程序域 string pathUserInfo = a.BaseDirectory + UserInfo.txt;/确定用户信息的文本位置 string readText = File.ReadAllLines(pathUserInfo, Encoding.Default);/逐行读取文本存入数组 return readText; private void btnStop_Click(object sender, RoutedEventArgs e) userList.RemoveAllUser(); onlineShow.Dispatcher.Invoke() = onlineShow.Text = 当前在线用户数:0); isExit = true; listener.Stop(); btnStart.IsEnabled = true; btnStop.IsEnabled = false; private void Window_Closing_1(object sender, System.ComponentModel.CancelEventArgs e) userList.RemoveAllUser(); isExit = true; listener.Stop(); 6.2客户端User类using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Net.Sockets;using System.IO;namespace Client_541307110114 public class User public string userName; public TcpClient client; public BinaryReader bReader; public BinaryWriter bWrite; public User(TcpClient client) this.client = client; NetworkStream ns = client.GetStream(); bReader = new BinaryReader(ns); bWrite = new BinaryWriter(ns); public void Close() if (bReader!=null) bReader.Close(); if (bWrite!=null) bWrite.Close(); if (client!=null) client.Close(); public void Send(string message) try bWrite.Write(message); bWrite.Flush(); catch (Exception ex) throw ex; public string Receive() try return bReader.ReadString(); catch (Exception) throw; Login代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Shapes;using System.Net.Sockets;using System.Threading;namespace Client_541307110114 / / Login.xaml 的交互逻辑 / public partial class Login : Window public User user; public int port; public bool isConnect; public TcpClient client; public Login() InitializeComponent(); client = new TcpClient(); port = 1005; isConnect = false; private void btnRegister_Click(object sender, RoutedEventArgs e) try if (isConnect = false) try client.Connect(, port); user = new User(client); isConnect = true; catch (Exception) MessageBox.Show(连接服务器失败!); Register reg = new Register(user); reg.Show(); catch (Exception ex) MessageBox.Show(连接失败!+ex); private void btnLogin_Click(object sender, RoutedEventArgs e) / 使用一个IntPtr类型值来存储加密字符串的起始点 IntPtr p = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(this.tbUserPassword.SecurePassword); / 使用.NET内部算法把IntPtr指向处的字符集合转换成字符串 string password = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p); if (tbUserName.Text = | password = ) MessageBox.Show(请输入用户名和密码!); return; try if (isConnect=false) try client.Connect(, port); user = new User(client); isConnect = true; catch (Exception) MessageBox.Show(连接服务器失败!); Task.Run() = Receive(); user.userName = tbUserName.Text; SendMessage(login, + user.userName + , + password); catch (Exception) MessageBox.Show(连接失败!); private void SendMessage(string message) try user.Send(message); catch(Exception ex) isConnect = false; MessageBox.Show(发送失败!+ex); private void Window_Closing_1(object sender, System.ComponentModel.CancelEventArgs e) if (isConnect) isConnect = false; SendMessage(logout, + user.userName); if (user!=null) user.Close(); public void Receive() string message; while (isConnect) try message = user.Receive(); catch isConnect = false; break; string split = message.Split(,); switch (split0) case login: if (split1 = user.userName)/如果接收到是自己的登陆成功 this.Dispatcher.Invoke() = isConnect = false; MessageBox.Show(登陆成功!); MainWindow mw = new MainWindow(user,LoginPage); mw.Show(); this.Hide(); ); break; case sorry: MessageBox.Show(请检查用户名或密码!); isConnect = false; break; default: break; private void Window_Loaded_1(object sender, RoutedEventArgs e) try client.Connect(, port); user = new User(client); isConnect = true; catch (Exception) MessageBox.Show(连接服务器失败!); private void close_Click(object sender, RoutedEventArgs e) this.Close(); private void Window_MouseDown_1(object sender, MouseButtonEventArgs e) if (e.LeftButton = MouseButtonState.Pressed) DragM

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论