版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、精选优质文档-倾情为你奉上计算机科学与信息技术学院实验报告学号:姓名: 班级:课程名称:C#网络应用编程实验名称:网络聊天程序上机实验性质: 综合性 设计性 验证实验实验时间:实验地点:实验设备:装有Microsoft Visual Studio 2008的计算机一、 实验要求将课本5.2.1的网络聊天程序加上一个广播消息功能。 二、 实验步骤 *服务器端操作*1、 创建一个名为服务器端的windows应用程序,将Form1.cs换名为MainForm.cs,设计界面如图所示。2、 在解决方案资源管理器中,添加一个名为User.cs的文件,用于保存于客户通信需要的信息,代码如下:using S
2、ystem.Net.Sockets;using System.IO;namespace SyncChatServer class User public TcpClient clientget; private set; public BinaryReader brget; private set; public BinaryWriter bwget; private set; public string userName get; set; public User(TcpClient client) this.client = client; NetworkStream networkStr
3、eam = client.GetStream(); br = new BinaryReader(networkStream); bw = new BinaryWriter(networkStream); public void Close() br.Close(); bw.Close(); client.Close(); 3、 在MainForm中添加对应的代码和事件:using System;using System.Collections.Generic;using System.Windows.Forms;/添加的命名空间引用using System.Net;using System.N
4、et.Sockets;using System.Threading;namespace SyncChatServer public partial class MainForm : Form / <summary>保存连接的所有用户</summary> private List<User> userList = new List<User>(); / <summary>使用的本机IP地址</summary> IPAddress localAddress; / <summary>监听端口</summary&
5、gt; private const int port = 22222; private TcpListener myListener; / <summary>是否正常退出所有接收线程</summary> bool isNormalExit = false; public MainForm() InitializeComponent(); listBoxStatus.HorizontalScrollbar = true; IPAddress addrIP = Dns.GetHostAddresses(Dns.GetHostName(); localAddress = ad
6、drIP0; buttonStop.Enabled = false; / <summary>【开始监听】按钮的Click事件</summary> private void buttonStart_Click(object sender, EventArgs e) myListener = new TcpListener(localAddress, port); myListener.Start(); AddItemToListBox(string.Format("开始在0:1监听客户连接", localAddress, port); /创建一个线程监
7、听客户端连接请求 Thread myThread = new Thread(ListenClientConnect); myThread.Start(); buttonStart.Enabled = false; buttonStop.Enabled = true; / <summary>接收客户端连接</summary> private void ListenClientConnect() TcpClient newClient = null; while (true) try newClient = myListener.AcceptTcpClient(); cat
8、ch /当单击“停止监听”或者退出此窗体时AcceptTcpClient()会产生异常 /因此可以利用此异常退出循环 break; /每接受一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息 User user = new User(newClient); Thread threadReceive = new Thread(ReceiveData); threadReceive.Start(user); userList.Add(user); AddItemToListBox(string.Format("0进入", newClient.Client.Remot
9、eEndPoint); AddItemToListBox(string.Format("当前连接用户数:0", userList.Count); / <summary> / 处理接收的客户端数据 / </summary> / <param name="userState">客户端信息</param> private void ReceiveData(object userState) User user = (User)userState; TcpClient client = user.client; w
10、hile (isNormalExit = false) string receiveString = null; try /从网络流中读出字符串,此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = user.br.ReadString(); catch if (isNormalExit = false) AddItemToListBox(string.Format("与0失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint); RemoveUser(user); break; AddItemToL
11、istBox(string.Format("来自0:1", user.client.Client.RemoteEndPoint, receiveString); string splitString = receiveString.Split(','); switch (splitString0) case "Login": user.userName = splitString1; SendToAllClient(user, receiveString); break; case "Logout": SendToAl
12、lClient(user, receiveString); RemoveUser(user); break; case "UniTalk": string unitalkString = receiveString.Substring(splitString0.Length + splitString1.Length + 2); AddItemToListBox(string.Format("0对1说:2", user.userName, splitString1, unitalkString); SendToClient(user, "uni
13、talk," + user.userName + "," + unitalkString); foreach (User target in userList) if (target.userName = splitString1 && user.userName != splitString1) SendToClient(target, "unitalk," + user.userName + "," + unitalkString); break; break; case "Brotalk&qu
14、ot;: string brotalkString = receiveString.Substring(splitString0.Length + 1); AddItemToListBox(string.Format("0说:1", user.userName, brotalkString); SendToClient(user, "brotalk," + user.userName + "," + brotalkString); SendToAllClient(user, "brotalk," + user.us
15、erName + "," + brotalkString); break; default: AddItemToListBox("什么意思啊:" + receiveString); break; / <summary> / 发送message给user / </summary> / <param name="user">指定发给哪个用户</param> / <param name="message">信息内容</param> private v
16、oid SendToClient(User user, string message) try /将字符串写入网络流,此方法会自动附加字符串长度前缀 user.bw.Write(message); user.bw.Flush(); AddItemToListBox(string.Format("向0发送:1", user.userName, message); catch AddItemToListBox(string.Format("向0发送信息失败", user.userName); / <summary>发送信息给所有客户</su
17、mmary> / <param name="user">指定发给哪个用户</param> / <param name="message">信息内容</param> private void SendToAllClient(User user, string message) string command = message.Split(',')0.ToLower(); if (command = "login") for (int i = 0; i < use
18、rList.Count; i+) SendToClient(userListi, message); if (userListi.userName != user.userName) SendToClient(user, "login," + userListi.userName); else if(command="logout") for (int i = 0; i < userList.Count; i+) if (userListi.userName != user.userName) SendToClient(userListi, mes
19、sage); else if(command="brotalk") for (int i = 0; i < userList.Count; i+) if (userListi.userName != user.userName) SendToClient(userListi, message); / <summary>移除用户</summary> / <param name="user">指定要删除的用户</param> private void RemoveUser(User user) userL
20、ist.Remove(user); user.Close(); AddItemToListBox(string.Format("当前连接用户数:0", userList.Count); private delegate void AddItemToListBoxDelegate(string str); / <summary>在ListBox中追加状态信息</summary> / <param name="str">要追加的信息</param> private void AddItemToListBox(s
21、tring str) if (listBoxStatus.InvokeRequired) AddItemToListBoxDelegate d = AddItemToListBox; listBoxStatus.Invoke(d, str); else listBoxStatus.Items.Add(str); listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1; listBoxStatus.ClearSelected(); / <summary>【停止监听】按钮的Click事件</summary> p
22、rivate void buttonStop_Click(object sender, EventArgs e) AddItemToListBox("开始停止服务,并依次使用户退出!"); isNormalExit = true; for (int i = userList.Count - 1; i >= 0; i-) RemoveUser(userListi); /通过停止监听让myListener.AcceptTcpClient()产生异常退出监听线程 myListener.Stop(); buttonStart.Enabled = true; buttonSto
23、p.Enabled = false; / <summary>关闭窗口时触发的事件</summary> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) if (myListener != null) /引发buttonStop的Click事件 buttonStop.PerformClick(); *服务器端操作*4、 创建一个名为客户端举例端的windows应用程序,将Form1.cs换名为MainForm.cs,设计界面如图所示。5、 在MainForm中添加对应的代码和事
24、件:using System;using System.Windows.Forms;/添加的命名空间引用using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;namespace SyncChatClient public partial class MainForm : Form private bool isExit = false; private TcpClient client; private BinaryReader br; private BinaryWriter bw;
25、public MainForm() InitializeComponent(); Random r = new Random(int)DateTime.Now.Ticks); textBoxUserName.Text = "hrf" + r.Next(100, 999); listBoxOnlineStatus.HorizontalScrollbar = true; / <summary> / 【连接服务器】按钮的Click事件 / </summary> private void buttonConnect_Click(object sender,
26、EventArgs e) buttonConnect.Enabled = false; try /此处为方便演示,实际使用时要将Dns.GetHostName()改为服务器域名 client = new TcpClient(Dns.GetHostName(), 22222); AddTalkMessage("连接成功"); catch AddTalkMessage("连接失败"); buttonConnect.Enabled = true; return; /获取网络流 NetworkStream networkStream = client.GetSt
27、ream(); /将网络流作为二进制读写对象 br = new BinaryReader(networkStream); bw = new BinaryWriter(networkStream); SendMessage("Login," + textBoxUserName.Text); Thread threadReceive = new Thread(new ThreadStart(ReceiveData); threadReceive.IsBackground = true; threadReceive.Start(); / <summary>处理接收的服
28、务器端数据</summary> private void ReceiveData() string receiveString = null; while (isExit = false) try /从网络流中读出字符串 /此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = br.ReadString(); catch if (isExit = false) MessageBox.Show("与服务器失去联系。"); break; string splitString= receiveString.Split(',&
29、#39;); string command = splitString0.ToLower(); switch (command) case "login": /格式:login,用户名 AddOnline(splitString1); break; case "logout": /格式:logout,用户名 RemoveUserName(splitString1); break; case "unitalk": /格式:unitalk,用户名,对话信息 /AddTalkMessage(splitString1 + ":rn&
30、quot;); /AddTalkMessage(receiveString.Substring( / splitString0.Length + splitString1.Length+2); AddTalkMessage(string.Format("0说:1", splitString1, receiveString.Substring( splitString0.Length + splitString1.Length + 2); break; case "brotalk": AddTalkMessage(string.Format("0
31、说:1", splitString1, receiveString.Substring( splitString0.Length + splitString1.Length + 2); break; default: AddTalkMessage("什么意思啊:" + receiveString); break; Application.Exit(); / <summary>向服务器端发送信息</summary> private void SendMessage(string message) try /将字符串写入网络流,此方法会自动附加
32、字符串长度前缀 bw.Write(message); bw.Flush(); catch AddTalkMessage("发送失败!"); / <summary>【发送】按钮的Click事件</summary> private void buttonSend_Click(object sender, EventArgs e) if (listBoxOnlineStatus.SelectedIndex != -1) /SendMessage("Talk," + listBoxOnlineStatus.SelectedItem + &
33、quot;," + textBoxSend.Text+"rn"); SendMessage("UniTalk," + listBoxOnlineStatus.SelectedItem + "," + textBoxSend.Text); textBoxSend.Clear(); else MessageBox.Show("没有选中一个用户,则为发送广播信息,确认发送?"); SendMessage("Brotalk," + listBoxOnlineStatus.SelectedIte
34、m + textBoxSend.Text); textBoxSend.Clear(); / <summary>关闭窗口时触发的事件</summary> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) /未与服务器连接前client为null if (client != null) SendMessage("Logout," + textBoxUserName.Text); isExit = true; br.Close(); bw.Close(); cl
35、ient.Close(); / <summary>在发送信息文本框中按下【Enter】键触发的事件</summary> private void textBoxSend_KeyPress(object sender, KeyPressEventArgs e) if (e.KeyChar = (char)Keys.Return) /触发buttonSend的Click事件 buttonSend.PerformClick(); private delegate void MessageDelegate(string message); / <summary> 在
36、richTextBoxTalkInfo中追加聊天信息</summary> private void AddTalkMessage(string message) if (richTextBoxTalkInfo.InvokeRequired) MessageDelegate d = new MessageDelegate(AddTalkMessage); richTextBoxTalkInfo.Invoke(d, new object message ); else richTextBoxTalkInfo.AppendText(message + Environment.NewLine); richTextBoxTalkInfo.ScrollToCaret(); private delegate void AddOnlineDelegate(string message); / <summary> 在listBoxOnlineStatus中添加在线的其它客户端信息</summary> private void AddOnline(string userName) if (listBoxOnlineStatus.InvokeRequired) AddOnlineDelegate d = n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 品牌建设与市场推广策略培训考核试卷
- 2024年全年货物运输保险合同
- 建筑安全施工中的国际标准与认证考核试卷
- 学生开学季校园安全培训考核试卷
- 卫生材料的质量保障与生产过程控制实施方案考核试卷
- 2024年专业建筑木工模型制作分包合作协议
- 2024年三人股东股权分配合同
- 2024年个体与福利机构儿童收养合同
- 2024年第9范文:新能源汽车电池回收处理服务合同
- 2(2024版)企业经营借款合同及担保协议
- “双减”背景下小学数学作业的创新设计方案六篇样本
- 北京市房山区2023-2024学年高二上学期期中地理试题 含解析
- 2024至2030年中国高岭土产业转移研究与目标企业分析咨询报告
- 期中测试卷及答案(共5套)(试题)-2024-2025学年四年级上册科学教科版
- 2024年秋八年级语文上册 第二单元 6《藤野先生》教学设计 新人教版
- 2024政务服务综合窗口人员能力与服务规范考试试题
- 2024年妇产科医生个人工作述职报告样本(3篇)
- 2024年第一季度压力性损伤质控工作总结分析
- 2024年湖北机场集团限公司楚天启航“A”春季校园招聘35人(高频重点提升专题训练)共500题附带答案详解
- 中国融通集团招聘笔试题
- ISO 55000-2024 资产管理 术语、综述和原则(中文版-雷泽佳翻译-2024)
评论
0/150
提交评论