C#套接字通信之UDP组播

news/2024/5/18 15:13:55 标签: c#, udp, 网络, 组播

文章目录

组播的概念

UDP信息传递的方式分三类,分别是

  • 单播 Unicast:客户端与服务器之间的点到点连接
  • 多播MultiCast:又称组播,是“一对一组”的通讯模式,加入同一个组的主机可以接受到此组内的所有数据。
  • 广播 BroadCast:主机之间“一对所有”的通讯模式,广播者可以向网络中所有主机发送信息。广播禁止在Internet宽带网上传输。

其中单播比较简单,在C#中可直接通过UdpClient点对点收发。

组播和单播的差别是,必须得有一个“组”的概念,然后才能进行组播,在C#中,通过client.JoinMulticastGroup来实现。

另外,组播对IP地址的范围有一定的要求:

起始IP截至IP适用范围
224.0.0.1224.0.0.255预留地址,最好不要乱用
224.0.1.0224.0.1.255公用地址,可用于互联网
224.0.2.0238.255.255.255用户可用,全网范围
239.0.0.0239.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接收到了。


http://www.niftyadmin.cn/n/319521.html

相关文章

Java中的Struts是什么?如何使用Struts

Struts是一个开放源代码的Java Web应用程序框架,它基于MVC(Model-View-Controller)架构设计,旨在简化Web应用程序的开发过程。本文将介绍Struts的基本概念,特性和使用方法。 Struts的基本概念 Struts是一个Web框架&a…

Java每日一练(20230514) 滑动窗、最大子序和、转罗马数字

目录 1. 滑动窗口最大值 🌟🌟 2. 最大子序和 🌟 3. 整数转罗马数字 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1.…

Jsp基于WEB操作系统课程教学网站的设计与实现(源代码+论文)

通过操作系统教学网站的建设,完成了对于操作系统课程的远程化授课。可以使学生不受时间空间的限制,通过网络对于这门课程进行学习。建立起了基于B/C的网络化教学系统。本网站采用当前最流行的JSP网络编程技术,可以实现数据的高效、动态、交互…

大数据Doris(十九):Doris索引介绍与前缀索引

文章目录 Doris索引介绍与前缀索引 一、Doris索引介绍 二、前缀索引 Doris索引介绍与前缀索引 一、Doris索引介绍 索引用于帮助快速过滤或查找数据。目前 Doris 主要支持两类索引: 内建的智能索引,包括前缀索引和 ZoneMap

SQL 常用函数总结(一)

聚合函数 1. COUNT() COUNT() 函数用于计算一个表格或查询结果集合中的行数。 语法:COUNT(column_name) 或 COUNT(*) column_name 是可选的,表示计算某一列的非空值数量。* 表示计算所有行的数量。 示例1:计算 users 表格中所有记录的数…

SpringBoot——默认页面在哪里?

简单介绍: 在之前我们创建了一个SpringBoot的应用程序,并且我们也启动了,但是我们都是在postman或者是在控制台看到了我们的界面,那么在浏览器中看到的界面其实只有一个: 这个界面其实就是SpringBoot的报错默认界面&a…

MySQL的事务

1、事务的概念 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。 事务是一个不可分割的工作逻辑单元&#xff…

为什么用对数收益率,而不是算数收益率 --因为可加性

核心就是对于单一投资品的收益率,对数收益率时序可加;对于不同投资品的截面收益率,应该用百分比收益率,因为它在截面上有可加性;另外对数收益率对建模有帮助。 如果我们考察单一投资品在总共 T 期内的表现,…