Udp通讯(零基础)

前面学习了Tcp通讯之后听老师同学们讲到Udp也可以通讯,实现还要跟简单,没有繁琐的连接,所以最近学习了一下,记录下来以便忘记,同时也发表出来与大家相互学习,下面是我自己写的一个聊天例子,实现了群聊私聊等功能。

通讯类(UdpInfo)

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Model
 8 {
 9     [Serializable]
10     public class UdpInfo
11     {
12         public string Name { get; set; }
13         public string Ip { get; set; }
14         public string Port { get; set; }
15         public string Message { get; set; }
16         public int Types { get; set; }//消息的类型
17         public bool IsFist { get; set; }//判断加载的成员是否是第一个
18         public string ToName { get; set; }//与谁私聊
19         public string LoginName { get; set; }//新加入成员的名字
20     }
21 }
View Code

 

服务器(Server)

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 using System.Net;
 11 using System.Net.Sockets;
 12 using System.Threading;
 13 using System.IO;
 14 using System.Runtime.Serialization.Formatters.Binary;
 15 using Model;
 16 
 17 namespace Server
 18 {
 19     public partial class forUdp : Form
 20     {
 21         public forUdp()
 22         {
 23             InitializeComponent();
 24         }
 25         UdpClient server = null;
 26         IPEndPoint ipEndPoint = null;
 27         List<IPEndPoint> pointList = new List<IPEndPoint>();//成员集合
 28         private delegate void BindDelegate(UdpInfo u);//(绑定信息)
 29         BindDelegate bd = null;
 30         private bool flag;//是否为添加的第一个成员
 31         private string loginName;
 32         private void Form1_Load(object sender, EventArgs e)
 33         {
 34             txtPort.Text = "9018";//默认的端口
 35         }
 36         public void Receices()//接收客户端的消息
 37         {
 38             while (true)
 39             {
 40                 try
 41                 {
 42                     byte[] bytes = server.Receive(ref ipEndPoint);//获取消息
 43                     UdpInfo u = DeserializeObject(bytes) as UdpInfo;
 44                     bd = new BindDelegate(BindRtb);
 45                     this.Invoke(bd, u);
 46                 }
 47                 catch (Exception)
 48                 {
 49                     server.Close();//有异常关闭服务
 50                 }
 51             }
 52         }
 53         public object DeserializeObject(byte[] pBytes)//反序列化二进制为对象
 54         {
 55             object newOjb = null;
 56             if (pBytes == null)
 57                 return newOjb;
 58             MemoryStream memory = new MemoryStream(pBytes);
 59             memory.Position = 0;
 60             BinaryFormatter formatter = new BinaryFormatter();
 61             newOjb = formatter.Deserialize(memory);
 62             memory.Close();
 63             return newOjb;
 64         }
 65         public byte[] SerializeObject(object pObj)//序列化对象为二进制的数
 66         {
 67             if (pObj == null)
 68                 return null;
 69             MemoryStream memory = new MemoryStream();
 70             BinaryFormatter formatter = new BinaryFormatter();
 71             formatter.Serialize(memory, pObj);
 72             memory.Position = 0;
 73             byte[] read = new byte[memory.Length];
 74             memory.Read(read, 0, read.Length);
 75             memory.Close();
 76             return read;
 77         }
 78         public void BindRtb(UdpInfo u) //添加信息,绑定信息
 79         {
 80             if(u.Types == 0)//如果消息类型为上线
 81             {
 82                 pointList.Add(ipEndPoint);//添加成员
 83                 //u.Name = "1";
 84                 //获取需要的基本信息
 85                 loginName = u.Name;
 86                 u.Ip = ipEndPoint.ToString().Split(':')[0];
 87                 u.Port = ipEndPoint.ToString().Split(':')[1];
 88                 byte[] bytes = SerializeObject(u);
 89                 ListViewItem item = new ListViewItem(u.Name);//绑定添加到成员列表上
 90                 item.SubItems.Add(u.Ip);
 91                 item.SubItems.Add(u.Port);
 92                 lvInfo.Items.Add(item);//显示成员信息
 93                 BindListView(loginName);//成员发生改变的时候,发送成员信息给客户端,刷新客户端的成员信息
 94             }
 95             else if (u.Types == 1)//如果消息的类型是群聊的话就执行
 96             {
 97                 foreach (ListViewItem items in lvInfo.Items)//循环每个成员
 98                 {
 99                     IPAddress ip = IPAddress.Parse(items.SubItems[1].Text);
100                     IPEndPoint ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text));
101                     byte[] bytes = SerializeObject(u);
102                     server.Send(bytes, bytes.Length, ipEndPoint);//给每个用户发送信息
103                 }
104             }
105             else if (u.Types == 2)//消息的类型是私聊
106             {
107                 foreach(ListViewItem items in lvInfo.Items)
108                 {
109                     //如果该成员是指定成员才发送信息
110                     if(u.ToName.Equals(items.SubItems[0].Text))
111                     {
112                         IPAddress ip = IPAddress.Parse(items.SubItems[1].Text);
113                         IPEndPoint ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text));
114                         byte[] bytes = SerializeObject(u);
115                         server.Send(bytes, bytes.Length, ipEndPoint);//发送消息给指定的用户
116                     }
117                 }
118             }
119             else if(u.Types == 3)//如果消息的类型是下线的话
120             {
121                 IPEndPoint ipEndPoint = null;
122                 foreach (ListViewItem items in lvInfo.Items)//循环每个成员
123                 {
124                     IPAddress ip = IPAddress.Parse(items.SubItems[1].Text);
125                     ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text));
126                     if(items.SubItems[0].Text.Equals(u.Name))
127                     {
128                         lvInfo.Items.Remove(items);//从ListView集合中移除  
129                         pointList.Remove(ipEndPoint);//从List<IPEndPoint>集合中移除
130                         continue;
131                     }
132                     byte[] bytes = SerializeObject(u);
133                     server.Send(bytes, bytes.Length, ipEndPoint);//给每个用户发送信息
134                 }
135             }
136             //服务器接收所有的消息
137             rtbMessage.Text += "\n" + u.Name + ":" + u.Message;
138         }
139         public void BindListView(string loginName) //有新成员加入的时候就绑定刷新成员列表
140         {
141             flag = true;
142             foreach (ListViewItem items in lvInfo.Items)//循环每个用户
143             {
144                 foreach (ListViewItem item in lvInfo.Items)//给每个用户发送全部的成员信息
145                 {
146                     UdpInfo u = new UdpInfo();
147                     u.Name = item.SubItems[0].Text.ToString();
148                     u.IsFist = flag;//添加第一个成员的时候因为要重新初始化客户端成员列表,而剩下的则不要初始化,所以要设置为true
149                     flag = false;
150                     u.LoginName = loginName;
151                     u.Message = "上线了!";
152                     u.Ip = item.SubItems[1].Text.ToString();
153                     u.Port = item.SubItems[2].Text.ToString();
154                     byte[] bytes = SerializeObject(u);
155                     IPAddress ip = IPAddress.Parse(items.SubItems[1].Text);
156                     IPEndPoint ipp = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text));//得到成员的IPEndPoint
157                     server.Send(bytes, bytes.Length, ipp);
158                 }
159             }
160         }
161         private void 结束程序ToolStripMenuItem_Click(object sender, EventArgs e)
162         {
163             server.Close();
164             this.Dispose();
165             Application.Exit();
166         }
167 
168         private void 运行程序ToolStripMenuItem_Click(object sender, EventArgs e)
169         {
170             rtbMessage.Text = "可以发送消息过来了!";
171             int port = Convert.ToInt32(txtPort.Text);
172             server = new UdpClient(port);
173             ipEndPoint = new IPEndPoint(IPAddress.Any, port);
174             Thread t = new Thread(new ThreadStart(Receices));
175             t.Start();
176         }
177     }
178 }
View Code

 

客户端(Client)

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading.Tasks;
  9 using System.Windows.Forms;
 10 using System.Net;
 11 using System.Net.Sockets;
 12 using System.Threading;
 13 using Model;
 14 using System.IO;
 15 using System.Runtime.Serialization.Formatters.Binary;
 16 
 17 namespace Client
 18 {
 19     public partial class forUdp : Form
 20     {
 21         public forUdp()
 22         {
 23             InitializeComponent();
 24         }
 25         UdpClient client = null;
 26         IPEndPoint ipEndPoints = null;
 27         private delegate void BindDelegate(UdpInfo u);
 28         BindDelegate bd = null;
 29         private void forUdp_Load(object sender, EventArgs e)
 30         {
 31             txtIP.Text = "192.168.1.109";
 32             txtPort.Text = "9018";
 33             txtName.Text = "小哈";
 34         }
 35 
 36         private void 运行程序ToolStripMenuItem_Click(object sender, EventArgs e)
 37         {
 38             rtbMessage.Text = "可以发送消息过去了!";
 39             int port = Convert.ToInt32(txtPort.Text);
 40             ipEndPoints = new IPEndPoint(IPAddress.Parse(txtIP.Text), port);
 41             client = new UdpClient();
 42             client.Connect(IPAddress.Parse(txtIP.Text), port);//关联此IP和端口
 43             Send(new UdpInfo() {Name = txtName.Text,Message = "上线了!", Types = 0 });
 44             Thread t = new Thread(new ThreadStart(Receices));
 45             t.Start();
 46         }
 47 
 48         public void Receices()//接收客户端的消息
 49         {
 50             while (true)
 51             {
 52                 try
 53                 {
 54                     byte[] bytes = client.Receive(ref ipEndPoints);
 55                     UdpInfo u = DeserializeObject(bytes) as UdpInfo;
 56                     bd = new BindDelegate(BindRtb);
 57                     this.Invoke(bd, u);
 58                 }
 59                 catch (Exception)
 60                 {
 61                     client.Close();
 62                 }
 63             }
 64         }
 65         public object DeserializeObject(byte[] pBytes)//反序列化二进制为对象
 66         {
 67             object newOjb = null;
 68             if (pBytes == null)
 69                 return newOjb;
 70             MemoryStream memory = new MemoryStream(pBytes);
 71             memory.Position = 0;
 72             BinaryFormatter formatter = new BinaryFormatter();
 73             newOjb = formatter.Deserialize(memory);
 74             memory.Close();
 75             return newOjb;
 76         }
 77         public byte[] SerializeObject(object pObj)//序列化对象为二进制的数
 78         {
 79             if (pObj == null)
 80                 return null;
 81             MemoryStream memory = new MemoryStream();
 82             BinaryFormatter formatter = new BinaryFormatter();
 83             formatter.Serialize(memory, pObj);
 84             memory.Position = 0;
 85             byte[] read = new byte[memory.Length];
 86             memory.Read(read, 0, read.Length);
 87             memory.Close();
 88             return read;
 89         }
 90         public void BindRtb(UdpInfo u)//将消息添加到消息框中
 91         {
 92             if (u.Types == 0)
 93             {
 94                 if (u.IsFist == true)
 95                     lvInfo.Items.Clear();
 96                 ListViewItem item = new ListViewItem(u.Name);
 97                 item.SubItems.Add(u.Ip);
 98                 item.SubItems.Add(u.Port);
 99                 lvInfo.Items.Add(item);
100             }
101             else if (u.Types == 3)//如果消息的类型是下线的话
102             {
103                 IPEndPoint ipEndPoint = null;
104                 foreach (ListViewItem items in lvInfo.Items)//循环每个成员
105                 {
106                     if (items.SubItems[0].Text.Equals(u.Name))
107                     {
108                         IPAddress ip = IPAddress.Parse(items.SubItems[1].Text);
109                         ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[2].Text));
110                         lvInfo.Items.Remove(items);//从ListView集合中移除  
111                         continue;
112                     }
113                 }
114             }
115             foreach (ListViewItem items in lvInfo.Items)
116             {
117                 if(items.SubItems[0].Text.Equals(u.LoginName))
118                     rtbMessage.Text += "\n" + u.Name + ":" + u.Message;
119             }
120         }
121         public void Send(UdpInfo u)//发送消息给服务器
122         {
123             byte[] bytes = SerializeObject(u);     
124             client.Send(bytes, bytes.Length);
125         }
126         private void 结束程序ToolStripMenuItem_Click(object sender, EventArgs e)
127         {
128             Send(new UdpInfo() { Name = txtName.Text, Message = "下线了!", Types = 3 });
129             client.Close(); 
130             Application.Exit();
131         }
132 
133         private void btnSend_Click(object sender, EventArgs e)
134         {
135             UdpInfo u = new UdpInfo() { 
136                 Name = txtName.Text, Message = rtbNews.Text, Types = 1
137             };
138             if (lvInfo.SelectedItems.Count > 0)//如果有选中的成员的话
139             {
140                 u.Types = 2;
141                 u.ToName = lvInfo.SelectedItems[0].SubItems[0].Text;
142             }
143             Send(u);
144             lvInfo.SelectedItems.Clear();//清除上一次的痕迹
145         }
146     }
147 }
View Code

 

转载于:https://www.cnblogs.com/LiuZhen/p/3503749.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/547018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VOC数据集格式转化成COCO数据集格式

VOC数据集格式转化成COCO数据集格式 一、唠叨 之前写过一篇关于coco数据集转化成VOC格式的博客COCO2VOC&#xff0c;最近读到CenterNet的官方代码&#xff0c;实现上则是将voc转化成coco数据格式&#xff0c;这样的操作我个人感觉很不习惯&#xff0c;也觉得有些奇葩&…

react native android6+拍照闪退或重启的解决方案

前言 android 6权限使用的时候需要动态申请&#xff0c;那么在使用rn的时候要怎么处理拍照权限问题呢&#xff1f;本文提供的是一揽子rn操作相册、拍照的解决方案&#xff0c;请看正文的提高班部分。 解决步骤 1、AndroidManifest.xml设置拍照权限&#xff1a; <uses-perm…

学术论文SCI、期刊、毕业设计中的图表专用软件

Origin Origin是由OriginLab公司开发的一个科学绘图、数据分析软件&#xff0c;支持在Microsoft Windows下运行。Origin支持各种各样的2D/3D图形。Origin中的数据分析功能包括统计&#xff0c;信号处理&#xff0c;曲线拟合以及峰值分析。 Origin中的曲线拟合是采用基于Lever…

常用的学术论文图表(折线图、柱状图)matplotlib python代码模板

最终选用了pythonMatplotlib。Matplotlib是著名Python的标配画图包&#xff0c;其绘图函数的名字基本上与 Matlab 的绘图函数差不多。优点是曲线精致&#xff0c;软件开源免费&#xff0c;支持Latex公式插入&#xff0c;且许多时候只需要一行或几行代码就能搞定。 然后小编经过…

史上最详细nodejs版本管理器nvm的安装与使用(附注意事项和优化方案)

使用场景 在Node版本快速更新迭代的今天&#xff0c;新老项目使用的node版本号可能已经不相同了&#xff0c;node版本更新越来越快&#xff0c;项目越做越多&#xff0c;node切换版本号的需求越来越迫切&#xff0c;传统卸载一个版本在安装另一个版本的方式太过于麻烦&#xf…

【TensorFlow】 基于视频时序LSTM的行为动作识别

简介 本文基于LSTM来完成用户行为识别。数据集来源&#xff1a;https://archive.ics.uci.edu/ml/machine-learning-databases/00240/ 此数据集一共有6种行为状态&#xff1a; 行走&#xff1b; 站立&#xff1b; 躺下&#xff1b; 坐下&#xff1b; 上楼&#xff1b; 下楼&am…

利用Asp.net MVC处理文件的上传下载

如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的&#xff0c;我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个&#xff0c;而这个控件的缺席给我们带来一些小问题。这篇文章主要说如何在Asp.net MVC中上传…

Python遍历文件夹下所有文件及目录

遍历文件夹中的所有子文件夹及子文件使用os.walk()方法非常简单。 语法格式大致如下&#xff1a; os.walk(top[, topdownTrue[, onerrorNone[, followlinksFalse]]]) top – 根目录下的每一个文件夹(包含它自己), 产生3-元组 (dirpath, dirnames, filenames)【文件夹路径, 文…

华为交换机telnet和ftp服务开启/关闭命令

1.telnet开启/关闭 在系统视图下 启用方式如下&#xff1a; telnet server enable //使能telnet服务关闭方式如下&#xff1a; undo telnet server //关闭telnet服务2.FTP开启/关闭 通过display ftp-server查看启用状态 如果已经启用&#xff0c;会在查看的命令中显示&#…

为什么用Spring来管理Hibernate?

为什么用Spring来管理Hibernate&#xff1f;为什么要用Hibernate框架&#xff1f;这个在《Hibernate介绍》博客中已经提到了。既然用Hibernate框架访问管理持久层&#xff0c;那为何又提到用Spring来管理以及整合Hibernate呢&#xff1f;首先我们来看一下Hibernate进行操作的步…

Python-Pandas之两个Dataframe的差异比较

昨天在外网找到一个比较dataframe的好库&#xff0c;叫datacompy&#xff0c;它的优点有&#xff1a; 1、可以把对比后的信息详情打印出来&#xff0c;比如列是否相等&#xff0c;行是否相等&#xff1b; 2、在数据中如果有不相等列&#xff0c;那么就只比较相同的列&#xf…

华为交换机如何通过tftp服务器上传下载文件

温馨提示:为了防止更新交换机配置文件操作失败,操作前交换机配置文件一定要做备份,可以通过copy vrpcfg.zip vrpcfg_backup.zip 工具/原料: windows电脑: Tftpd64 SecureCRT USB转串口,串口转RJ45 console线 2米网线 华为交换机S3700一台 方法/步骤: 1.准备材料,按照下…

js节流函数和js防止重复提交的N种方法

应用情景 经典使用情景&#xff1a;js的一些事件&#xff0c;比如&#xff1a;onresize、scroll、mousemove、mousehover等&#xff1b; 还比如&#xff1a;手抖、手误、服务器没有响应之前的重复点击&#xff1b; 这些都是没有意义的&#xff0c;重复的无效的操作&#xff…

使用IPFS集群搭建创建私有IPFS网络

基本介绍 IPFS 网络分两类: 公有私有 对于大多数商用应用尤其是企业级解决方案而言&#xff0c;需要对自身数据有完全的控制&#xff0c;这种场合公有IPFS网络并不适用&#xff0c;搭建私有IPFS往往是这类应用的必要需求。 本文我们讲解创建一个私有 IPFS 网络的过程&#xf…

MongoDB基础介绍安装与使用

MongoDB已经日益成为流程和主流的数据库了&#xff0c;原因有两个&#xff1a;第一个就是技术优势&#xff0c;第二就是便利性&#xff0c;个人使用部署都很方便。 MongoDB的优缺点&#xff0c;以及使用场景 优点&#xff1a; 面向文档存储&#xff08;自由读高&#xff0c;…

python调用cv2.findContours时报错:ValueError: not enough values to unpack (expected 3, got 2)

python调用cv2.findContours时报错&#xff1a;ValueError: not enough values to unpack (expected 3, got 2) OpenCV旧版&#xff0c;返回三个参数&#xff1a; im2, contours, hierarchy cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 要想返回三个参数…

优先级队列用的的数据结构

2019独角兽企业重金招聘Python工程师标准>>> 优先级队列和队列没有本质的区别 只是 每次出队列的时候出队列中优先级最高的 这里假定数字越小&#xff0c;优先级越高 优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。 通…

公网访问阿里云数据库MongoDB——填坑笔记

业务情景 两台服务器&#xff0c;一台阿里云ECS云服务器&#xff08;专用网络&#xff09;&#xff0c;另一台是阿里云数据库MongoDB&#xff0c;处于安全考虑MongoDB是不运行外网连接的&#xff0c;那接下来就看怎么实现公网访问。 看到上面红色的网络类型描述&#xff0c;有…

华为S5700交换机开启telnet远程登陆配置(推荐)

实验目标: 电脑PC1经过S3700交换机,telnet远程登录到S5700交换机。 连接拓扑图如下:(测试时用实物测试) 一、配置S5700交换机。 1.交换机开启Telnet服务 <Huawei>system-view Enter system view, return user view with Ctrl+Z. [Huawei]sysname LSW1 [LSW1]

2021最新Python量化A股投资必赚策略

一、板块信息&#xff1a; 1、每隔30分钟后台自动采集一个开盘啦的板块信息&#xff08;9:15开始到15:00是股票开市时间&#xff0c;如果15点以后已经采集过数据&#xff0c;就不需要重复采集&#xff0c;避免频繁采集被网站屏蔽&#xff09;。按照codelist.txt列表&#xff0…