




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、using System;using System.Collections.Generic;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Threading;namespace AsyncTcpServer public partial class FormServer : Form / <summary>保存连接的所有用户</summary> private List<User> userList = new List<User>
2、;(); / <summary>使用的本机IP地址</summary> IPAddress localAddress; / <summary>监听端口</summary> private const int port = 51888; private TcpListener myListener; / <summary>是否正常退出所有接收线程</summary> bool isExit = false; public FormServer() InitializeComponent(); listBoxStatus.Ho
3、rizontalScrollbar = true; IPAddress addrIP = Dns.GetHostAddresses(Dns.GetHostName(); /localAddress = addrIP0; foreach (var ip in addrIP) /判断是否为IPv4地址 if (ip.AddressFamily = AddressFamily.InterNetwork) localAddress = ip; break; buttonStop.Enabled = false; / <summary>【开始监听】按钮的Click事件</summary
4、> private void buttonStart_Click(object sender, EventArgs e) myListener = new TcpListener(localAddress, port); myListener.Start(); AddItemToListBox(string.Format("开始在0:1监听客户连接", localAddress, port); Thread myThread = new Thread(ListenClientConnect); myThread.Start(); buttonStart.Enabled
5、 = false; buttonStop.Enabled = true; / <summary>监听客户端请求</summary> private void ListenClientConnect() TcpClient newClient = null; while (true) ListenClientDelegate d = new ListenClientDelegate(ListenClient); IAsyncResult result = d.BeginInvoke(out newClient, null, null); /使用轮询方式来判断异步操作是否完
6、成 while (result.IsCompleted = false) if (isExit) break; Thread.Sleep(250); /获取Begin方法的返回值和所有输入/输出参数 d.EndInvoke(out newClient, result); if (newClient != null) /每接受一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息 User user = new User(newClient); Thread threadReceive = new Thread(ReceiveData); threadReceive.Start(user
7、); userList.Add(user); AddItemToListBox(string.Format("0进入", newClient.Client.RemoteEndPoint); AddItemToListBox(string.Format("当前连接用户数:0", userList.Count); else break; private delegate void ListenClientDelegate(out TcpClient client); / <summary>接受挂起的客户端连接请求</summary>
8、private void ListenClient(out TcpClient newClient) try newClient = myListener.AcceptTcpClient(); catch newClient = null; / <summary>处理接收的客户端数据</summary> private void ReceiveData(object userState) User user = (User)userState; TcpClient client = user.client; while (isExit = false) string r
9、eceiveString = null; ReceiveMessageDelegate d = new ReceiveMessageDelegate(ReceiveMessage); IAsyncResult result = d.BeginInvoke(user, out receiveString, null, null); /使用轮询方式来判断异步操作是否完成 while (result.IsCompleted = false) if (isExit) break; Thread.Sleep(250); /获取Begin方法的返回值和所有输入/输出参数 d.EndInvoke(out r
10、eceiveString, result); if(receiveString=null) if (isExit = false) AddItemToListBox(string.Format("与0失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint); RemoveUser(user); break; AddItemToListBox(string.Format("来自0:1", user.client.Client.RemoteEndPoint, receiveString); string splitStr
11、ing = receiveString.Split(','); switch (splitString0) case "Login": user.userName = splitString1; AsyncSendToAllClient(user, receiveString); break; case "Logout": AsyncSendToAllClient(user, receiveString); RemoveUser(user); return; case "Talk": string talkString
12、 = receiveString.Substring(splitString0.Length + splitString1.Length + 2); AddItemToListBox(string.Format("0对1说:2", user.userName, splitString1, talkString); AsyncSendToClient(user, "talk," + user.userName + "," + talkString); foreach (User target in userList) if (targe
13、t.userName = splitString1 && user.userName != splitString1) AsyncSendToClient(target, "talk," + user.userName + "," + talkString); break; break; default: AddItemToListBox("什么意思啊:" + receiveString); break; delegate void ReceiveMessageDelegate(User user, out strin
14、g receiveMessage); / <summary>接受客户端发来的信息</summary> private void ReceiveMessage(User user, out string receiveMessage) try receiveMessage = user.br.ReadString(); catch (Exception ex) AddItemToListBox(ex.Message); receiveMessage = null; / <summary>异步发送message给user</summary> priv
15、ate void AsyncSendToClient(User user, string message) SendToClientDelegate d = new SendToClientDelegate(SendToClient); IAsyncResult result = d.BeginInvoke(user, message, null, null); while (result.IsCompleted = false) if (isExit) break; Thread.Sleep(250); d.EndInvoke(result); private delegate void S
16、endToClientDelegate(User user, string message); / <summary>发送message给user</summary> private void SendToClient(User user, string message) try /将字符串写入网络流,此方法会自动附加字符串长度前缀 user.bw.Write(message); user.bw.Flush(); AddItemToListBox(string.Format("向0发送:1", user.userName, message); cat
17、ch AddItemToListBox(string.Format("向0发送信息失败", user.userName); / <summary>异步发送信息给所有客户</summary> private void AsyncSendToAllClient(User user, string message) string command = message.Split(',')0.ToLower(); if (command = "login") for (int i = 0; i < userList.C
18、ount; i+) AsyncSendToClient(userListi, message); if (userListi.userName != user.userName) AsyncSendToClient(user, "login," + userListi.userName); else if (command = "logout") for (int i = 0; i < userList.Count; i+) if (userListi.userName != user.userName) AsyncSendToClient(use
19、rListi, message); / <summary>移除用户</summary> private void RemoveUser(User user) userList.Remove(user); user.Close(); AddItemToListBox(string.Format("当前连接用户数:0", userList.Count); private delegate void AddItemToListBoxDelegate(string str); / <summary>在ListBox中追加状态信息</summ
20、ary> / <param name="str">要追加的信息</param> private void AddItemToListBox(string str) if (listBoxStatus.InvokeRequired) AddItemToListBoxDelegate d = AddItemToListBox; listBoxStatus.Invoke(d, str); else listBoxStatus.Items.Add(str); listBoxStatus.SelectedIndex = listBoxStatus.Ite
21、ms.Count - 1; listBoxStatus.ClearSelected(); / <summary>【停止监听】按钮的Click事件</summary> private void buttonStop_Click(object sender, EventArgs e) AddItemToListBox("开始停止服务,并依次使用户退出!"); isExit = true; for (int i = userList.Count - 1; i >= 0; i-) RemoveUser(userListi); /通过停止监听让myLis
22、tener.AcceptTcpClient()产生异常退出监听线程 myListener.Stop(); buttonStart.Enabled = true; buttonStop.Enabled = false; / <summary>关闭窗口时触发的事件</summary> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) if (myListener != null) /引发buttonStop的Click事件 buttonStop.PerformClick(); u
23、sing System;using System.ComponentModel;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;namespace AsyncTcpClient public partial class FormClient : Form /是否正常退出 private bool isExit = false; private TcpClient client; private BinaryReader br;
24、private BinaryWriter bw; /BackgroundWorker connectWork = new BackgroundWorker(); public FormClient() InitializeComponent(); this.StartPosition = FormStartPosition.CenterScreen; Random r = new Random(int)DateTime.Now.Ticks); textBoxUserName.Text = "user" + r.Next(100, 999); listBoxOnline.Ho
25、rizontalScrollbar = true; /connectWork.DoWork += new DoWorkEventHandler(connectWork_DoWork); /connectWork.RunWorkerCompleted += / new RunWorkerCompletedEventHandler(connectWork_RunWorkerCompleted); /ConnectToServer(); / <summary>异步方式与服务器进行连接</summary> void ConnectToServer() client = new
26、TcpClient(); /此处仅为方便本机调试,实际使用时要将Dns.GetHostName()改为服务器域名 IAsyncResult result = client.BeginConnect(Dns.GetHostName(), 51888, null, null); while (result.IsCompleted = false) Thread.Sleep(100); AddStatus("."); try client.EndConnect(result); AddStatus("连接成功"); /获取网络流 NetworkStream n
27、etworkStream = client.GetStream(); /将网络流作为二进制读写对象 br = new BinaryReader(networkStream); bw = new BinaryWriter(networkStream); AsyncSendMessage("Login," + textBoxUserName.Text); Thread threadReceive = new Thread(new ThreadStart(ReceiveData); threadReceive.IsBackground = true; threadReceive.
28、Start(); catch (Exception ex) AddStatus("连接失败:" + ex.Message); buttonConnect.Enabled = true; / <summary> / 【连接服务器】按钮的Click事件 / </summary> private void buttonConnect_Click(object sender, EventArgs e) buttonConnect.Enabled = false; AddStatus("开始连接."); ConnectToServer();
29、 / <summary>处理接收的服务器端数据</summary> private void ReceiveData() string receiveString = null; while (isExit = false) ReceiveMessageDelegate d = new ReceiveMessageDelegate(ReceiveMessage); IAsyncResult result = d.BeginInvoke(out receiveString, null, null); /使用轮询方式来判断异步操作是否完成 while (result.IsC
30、ompleted = false) if (isExit) break; Thread.Sleep(250); /获取Begin方法的返回值和所有输入/输出参数 d.EndInvoke(out receiveString, result); if(receiveString=null) if (isExit = false) MessageBox.Show("与服务器失去联系。"); break; string splitString = receiveString.Split(','); string command = splitString0.ToLo
31、wer(); switch (command) case "login": /格式:login,用户名 AddOnline(splitString1); break; case "logout": /格式:logout,用户名 RemoveUserName(splitString1); break; case "talk": /格式:talk,用户名,对话信息 AddTalkMessage(splitString1 + ":rn"); AddTalkMessage(receiveString.Substring(
32、splitString0.Length + splitString1.Length + 2); break; Application.Exit(); / <summary>发送信息状态的数据结构</summary> private struct SendMessageStates public SendMessageDelegate d; public IAsyncResult result; / <summary>异步向服务器端发送数据</summary> private void AsyncSendMessage(string message
33、) SendMessageDelegate d = new SendMessageDelegate(SendMessage); IAsyncResult result = d.BeginInvoke(message, null, null); while (result.IsCompleted = false) if (isExit) return; Thread.Sleep(50); SendMessageStates states = new SendMessageStates(); states.d = d; states.result = result; Thread t = new
34、Thread(FinishAsyncSendMessage); t.IsBackground = true; t.Start(states); / <summary>处理接收的服务器端数据</summary> private void FinishAsyncSendMessage(object obj) SendMessageStates states = (SendMessageStates)obj; states.d.EndInvoke(states.result); delegate void SendMessageDelegate(string message)
35、; / <summary>向服务器端发送数据</summary> private void SendMessage(string message) try bw.Write(message); bw.Flush(); catch AddStatus("发送失败!"); / <summary>【发送】按钮的Click事件</summary> private void buttonSend_Click(object sender, EventArgs e) if (listBoxOnline.SelectedIndex != -1
36、) AsyncSendMessage("Talk," + listBoxOnline.SelectedItem + "," + textBoxSend.Text+"rn"); textBoxSend.Clear(); else MessageBox.Show("请先在当前在线中选择一个对话者"); delegate void ReceiveMessageDelegate(out string receiveMessage); / <summary>读取服务器发过来的信息</summary>
37、private void ReceiveMessage(out string receiveMessage) receiveMessage = null; try receiveMessage = br.ReadString(); catch(Exception ex) AddStatus(ex.Message); private delegate void AddTalkMessageDelegate(string message); / <summary>向richTextBoxTalkInfo中添加聊天记录</summary> private void AddTa
38、lkMessage(string message) if (richTextBoxTalkInfo.InvokeRequired) AddTalkMessageDelegate d = new AddTalkMessageDelegate(AddTalkMessage); richTextBoxTalkInfo.Invoke(d, new object message ); else richTextBoxTalkInfo.AppendText(message); richTextBoxTalkInfo.ScrollToCaret(); private delegate void AddStatusDelegate(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 建筑工地个人工作总结(14篇)
- 舟山市定海区第三社会福利院招聘笔试真题2024
- 西双版纳州勐海县教体系统招聘笔试真题2024
- 矿石加工中的化学工艺安全技术考核试卷
- 管道工程流体力学基础考核试卷
- 布艺家居产品安全性与风险评估考核试卷
- 杂粮加工园区规划与管理考核试卷
- 财务经理竞聘演讲范文(13篇)
- 四川省泸州市泸县普通高中共同体2024-2025学年高一下学期期中考试物理试题含答案
- 箱包品牌视觉识别系统设计考核试卷
- 动土作业安全技术交底
- 手术室护理质量控制讲解
- 大学物业服务月考核评价评分表
- GB 36893-2024空气净化器能效限定值及能效等级
- 19G522-1钢筋桁架混凝土楼板图集
- RPA财务机器人开发与应用 课件 6.1 RPA网银付款机器人
- 软件开发中介服务协议范本
- 云南省昆明市2025届高三年级第二次联考+物理试卷
- 企业宣传与品牌形象设计手册
- 别墅设备维护方案
- DL∕T 1917-2018 电力用户业扩报装技术规范
评论
0/150
提交评论