C#套接字(Socket)通信之UDP组播详解
作者:微小冷 发布时间:2022-06-11 05:49:52
组播的概念
UDP信息传递的方式分三类,分别是
单播 Unicast:客户端与服务器之间的点到点连接
多播MultiCast:又称组播,是“一对一组”的通讯模式,加入同一个组的主机可以接受到此组内的所有数据。
广播 BroadCast:主机之间“一对所有”的通讯模式,广播者可以向网络中所有主机发送信息。广播禁止在Internet宽带网上传输。
其中单播比较简单,在C#中可直接通过UdpClient点对点收发。
组播和单播的差别是,必须得有一个“组”的概念,然后才能进行组播,在C#中,通过client.JoinMulticastGroup来实现。
另外,组播对IP地址的范围有一定的要求:
起始IP | 截至IP | 适用范围 | |
---|---|---|---|
224.0.0.1 | 224.0.0.255 | 预留地址,最好不要乱用 | |
224.0.1.0 | 224.0.1.255 | 公用地址,可用于互联网 | |
224.0.2.0 | 238.255.255.255 | 用户可用,全网范围 | |
239.0.0.0 | 239.255.255.255 | 本地 |
其中224.0.0.0
也是预留的组播地址,但保留不做分配。
简单示例
下面再顶级语句中做一个简单的示例
using System.Net;
using System.Net.Sockets;
using System.Text;
static void Main()
{
UdpClient client = new UdpClient(5566);
client.JoinMulticastGroup(IPAddress.Parse("235.5.6.8"));
IPEndPoint multicast = new IPEndPoint(IPAddress.Parse("234.5.6.7"), 7788);
byte[] buf = Encoding.Default.GetBytes("Hello from multicast");
Thread t = new Thread(new ThreadStart(RecvThread));
t.IsBackground = true;
t.Start();
while (true)
{
client.Send(buf, buf.Length, multicast);
Thread.Sleep(1000);
}
}
static void RecvThread()
{
UdpClient client = new UdpClient(7788);
client.JoinMulticastGroup(IPAddress.Parse("234.5.6.7"));
IPEndPoint multicast = new IPEndPoint(IPAddress.Parse("235.5.6.8"), 5566);
while (true)
{
byte[] buf = client.Receive(ref multicast);
string msg = Encoding.Default.GetString(buf);
Console.WriteLine(msg);
}
}
Main();
函数RecvThread中,定义了一个端口号为7778的UDP客户端,并通过JoinMulticastGroup添加了234.5.6.7这个IP地址。在死循环中,让client不断接收来自multicast的信息,其中multicast是地址为235.5.6.8,端口为5566的终端。
Main函数则创建了端口为5566的客户端,然后不断地向234.5.6.7:7788发送消息。
这个示例程序运行之后,命令行中会不断地输出
Hello from multicast
但这个示例其实并没有体现出“组播”的特点,原因在于上面的代码只用了一个地址,虽然用到了组播的模式,但实际操作上来看,还是一对一的。
组播的优势
下面稍微修改一下代码,首先在RecvThread中新增一个IP
client.JoinMulticastGroup(IPAddress.Parse("234.5.6.9"));
然后在Main中新增一组发给新IP的信息,类似下面这样
static void Main()
{
UdpClient client = new UdpClient(5566);
client.JoinMulticastGroup(IPAddress.Parse("235.5.6.8"));
IPEndPoint multi1 = new IPEndPoint(IPAddress.Parse("234.5.6.7"), 7788);
IPEndPoint multi2 = new IPEndPoint(IPAddress.Parse("234.5.6.9"), 7788);
byte[] buf1 = Encoding.Default.GetBytes("Hello multi1");
byte[] buf2 = Encoding.Default.GetBytes("Hello multi2");
Thread t = new Thread(new ThreadStart(RecvThread));
t.IsBackground = true;
t.Start();
while (true)
{
client.Send(buf1, buf1.Length, multi1);
client.Send(buf2, buf2.Length, multi2);
Thread.Sleep(1000);
}
}
从而命令行输出就会变成
Hello multi1
Hello multi2
也就是说,发给两个不同IP地址的信息,都被client
接收到了。
来源:https://blog.csdn.net/m0_37816922/article/details/130161039


猜你喜欢
- 在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源。但是,GC有的时并不
- IDEA安装后找不到.vmoptions文件在安装IDEA后在C盘的C:\Users\你的电脑用户名.IntelliJIdea2019.1\
- 一、实现对ScrollViewer样式的自定义主要包括:1、滚动条宽度设置2、滚动条颜色3、滚动条圆角4、滚动条拉动时的效果mouseove
- Nacos简介Nacos 英文全称为 Dynamic Naming and Configuration Service,是一个由阿里巴巴团队
- 在说struts2的线程安全之前,先说一下,什么是线程安全?这是一个网友讲的。如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会
- static 表示静态,它可以修饰属性,方法和代码块。1.static修饰属性(类变量),那么这个属性就可以用类名.属性名来访问,也就是使这
- Spring Boot 项目之热部署配置前言所谓热部署,简单来说,就是代码修改后不需重启项目就可自动加载出新的内容。注意:热部署在 debu
- 在很多的Android项目中都需要用户登录、注册。这样的话在开发中做好保护用户密码的工作就显得尤为重要。这里我把自己的密码保护方法记录下来。
- 一:在函数入参中使用通配符@AspectJ支持3种通配符* :匹配任意字符,但它只能匹配上下文中的一个元素... :匹配任意字符,可以匹配上
- Notification的作用通知(Notification)是Android系统中比较有特色的一个功能。当某个应用程序希望向用户发出一些提
- 今天启动springboot项目时失败了解决检查原因发现是启动类的MapperScan("")的值写到类名了,改成类所在
- 1 需求描述我们现在要干一个什么事情呢,我们要在浏览器输入一个请求地址,然后我们的后端就给我返回一个User对象即可,并且我希望以Json的
- 我们都知道在一些特殊的场景,我们需采用特殊的编码格式,如:UTF-8,但是系统默认的编码为ISO-8859-1那么我们就需要将编码转换为我们
- 一、需求背景有时候,我们需要在屏幕上显示新的信息,同时移除旧的信息,一般情况下我们通过VISIBILITY或者GONE来对需要显示或者隐藏的
- 本文实例为大家分享了C#以流方式读socket超时设置的具体代码,供大家参考,具体内容如下using System;using System
- 什么是emoji表情emoji表情是一种表情符号,在代码中它现在其实是一组遵循Unicode的编码,即每一个表情符号都对应了一个Unicod
- 前言初识Android PowerManagerService省电模式 让我们省电模式的概念有了初步的认识,Androi
- 本文实例分析了C#泛型用法。分享给大家供大家参考。具体分析如下:这里演示如何创建具有单个类型参数的自定义泛型列表类,以及如何实现 IEnum
- 语法糖指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程
- 1.服务配置中心1.1 服务配置中心介绍首先我们来看一下,微服务架构下关于配置文件的一些问题:1.配置文件相对分散。在一个微服务架构下,配置