小工具知识网

当前位置: 首页 > 行业知识 > 【Linux C | 网络编程】广播概念、UDP实现广播的C语言例子

行业知识

【Linux C | 网络编程】广播概念、UDP实现广播的C语言例子

2026-11-07 00:04:52 来源:互联网转载

博客主页:https://blog.csdn.net/wkd_007

博客内容:嵌入式开发、Linux、C语言、C++、数据结构、音视频

本文内容:介绍广播概念、UDP实现广播的C语言例子

金句分享:你不能选择最好的,但最好的会来选择你——泰戈尔

⏰发布时间⏰:2024-03-06 00:10:30

本文未经允许,不得转发!!!

目录

  • 一、广播概述
  • 二、广播地址
  • 三、UDP单播 和 UDP广播 的比较
    • ✨3.1 UDP单播过程
    • ✨3.2 UDP广播过程
    • 四、UDP实现广播的例子
    • 五、总结

      一、广播概述

      在网络编程中,有三种常见的通信方式:单播、广播、多播(组播),这三种方式对比如下表:

      类型IPv4IPv6TCPUDP所标识接口数递送到的接口数
      单播支持支持支持支持一个一个
      广播支持支持全体全体
      多播可选支持支持一组整个组

      广播的概念

      广播是允许一台主机 向 本地子网内所有主机 发送消息的一种通信方式。发送的广播分组会去往子网上的所有主机,包括发送者自身。

      • 广播只支持IPv4,不支持IPv6:使用广播的IPv4应用程序一旦移植到IPv6,就必须使用多播重新编写;
      • 广播支持UDP或原始IP,不支持TCP。

        广播的用途

        • 资源发现:知道子网中有我们想找的资源,但不知道其具体IP地址,可以往该子网中发一个广播,该资源主机收到广播后处理并回复,非资源主机不处理。举例:NVR发送广播搜索局域网内的IPC。
        • 减少分组流通。

          广播的缺点

          子网内未参与相应广播的所有主机也会沿着协议栈向上完整地处理收取的广播数据报,直到该数据报在UDP层处理时才被丢弃。


          二、广播地址

          广播的实现需要往广播地址发送广播分组。任何子网中最后一个IP地址就是广播地址。如果以{子网ID,主机ID}表示一个IP地址,则广播地址分为下面两种,-1表示所有位都位1:

          • 1、子网定向广播地址:{子网ID,-1}。这是子网上所有接口的广播地址。举例来说,假设有一个 192.168.1/24 的子网,那么这个子网中最后一个IP就是 192.168.1.255/24 ,它就是该子网所有接口的子网定向广播地址。通常,路由器不转发目的地址为子网定向广播地址的数据报。
          • 2、受限广播地址:{-1,-1} 或 255.255.255.255。路由器从不转发目的地址为255.255.255.255的IP数据报。当应用程序设置了SO_BROADCAST套接字选项,且发送目的地址为255.255.255.255的UDP数据报时,大多数主机会将该目的地址转换成外出接口的子网定向广播地址并发送到路由器。

            255.255.255.255用十六进制表示就是0xffffffff。在Linux系统中,定义了一个宏INADDR_BROADCAST来表示受限广播地址,该宏定义在头文件中,定义如下:

            /* Address to send to all hosts.  */#define INADDR_BROADCAST        ((in_addr_t) 0xffffffff)

            三、UDP单播 和 UDP广播 的比较

            ✨3.1 UDP单播过程

            下图说明了一个UDP数据报在单播情况下,怎样到达目的地的:

            • 发送主机(图中最左边):

              • ①进程在一个UDP套接字上调用sendto往IP地址192.168.42.3端口7433发送一个数据报;
              • ②UDP层对它冠以一个UDP首部后把UDP数据报传递到IP层
              • ③IP层对它冠以一个IPv4首部,确定其外出接口,在以太网情况下还激活ARP把目的IP地址映射成相应的以太网地址:

                00:0a:95:79:bc:b4。

              • ④该分组然后作为一个目的以太网地址为这个48位地址的以太网帧发送出去。该以太网帧的帧类型字段值为表示IPv4分组的0x0800。
              • 目的主机(图中最右边):

                • ①目的主机的以太网接口看到该帧后,比较并确定该帧的目的地址和自己以太网地址相同,于是读入该帧。由于帧类型是0x0800,该帧的分组被置于IP输入队列。
                • ②IP层处理该分组会先比较该分组的目的地址,确定是本机IP地址之一才接受该分组,接着查看IPv4首部的协议字段,值为表示UDP的17,于是将该分组承载的数据报传递到UDP层。
                • ③UDP层检查该数据报的目的端口,把该数据报置于相应套接字的接收队列,必要时会唤醒阻塞在该相应输入操作的进程,由进程读取这个新收取的数据报。
                • 其他主机(图中中间):

                  • ①非目的主机的以太网口看到该帧后,比较该帧目的地址和自己以太网地址,比较结果不相同,于是忽略了这个帧。

                    ✨3.2 UDP广播过程

                    下图说明了一个UDP数据报在广播情况下,怎样到达目的地的:

                    • 发送主机(图中最左边):

                      • ①进程在一个UDP套接字上调用sendto往IP地址192.168.42.255端口520发送一个数据报;
                      • ②UDP层对它冠以一个UDP首部后把UDP数据报传递到IP层;
                      • ③IP层对它冠以一个IPv4首部,确定其外出接口,因为目的地址是子网定向广播地址,所以映射为48位全为1的以太网地址:ff:ff:ff:ff:ff:ff。
                      • ④该分组作为一个目的以太网地址为ff:ff:ff:ff:ff:ff的以太网帧发送出去,使得该子网的每个以太网接口(包括自身主机接口)都会接收到该帧。该以太网帧的帧类型字段值为表示IPv4分组的0x0800。
                      • 子网内所有主机(包括自身主机):

                        • ①子网内的所有主机的以太网接口看到该帧后,因为目的地址是ff:ff:ff:ff:ff:ff,都会接收该帧。由于帧类型是0x0800,该帧的分组传递到IP层。
                        • ②IP层确定该分组目的地址为广播地址后,会接受该分组,接着查看IPv4首部的协议字段,值为表示UDP的17,于是将该分组承载的数据报传递到UDP层。
                        • ③UDP层检查该数据报的目的端口,如果接收到该数据报的主机没有任何进程绑定值为520的UDP端口,则该主机的UDP代码会丢弃已收取的数据报,如图中中间主机。如果接收到该数据报的主机存在进程绑定了值为520的UDP端口,那么该进程把该数据报置于相应套接字的接收队列,必要时会唤醒阻塞在该相应输入操作的进程,由进程读取这个新收取的数据报。

                          四、UDP实现广播的例子

                          下面给出一个使用UDP实现广播的例子,代码是之前文章的例子 入门知识:UDP协议、一个最简单的UDP客户端、一个最简单的UDP服务端 。

                          只需要在原本客户端修改两个地方就可以发送UDP广播数据报了:一个是在sendto之前设置套接字选项SO_BROADCAST;另一个是将sendto的目的地址设置为广播地址,这里使用INADDR_BROADCAST。

                          发送UDP广播客户端步骤:

                          • 1、创建UDP套接字socket;
                          • 2、准备广播地址和端口;
                          • 3、设置广播套接字选项 SO_BROADCAST;
                          • 4、使用 sendto 发送广播数据报;
                          • 5、处理应答
                          • 6、关闭

                            UDP广播客户端代码也很简单,如下:

                            // brocastCli.c#include #include #include #include #include #include #define USE_BRORDCAST 1int main(){// 1、创建UDP套接字socketint sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfdperror("setsockopt");close(sockfd);return -1;}#elseif (inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) recvline[n] = 0 ;/*null terminate */printf("recvfrom ip=[%s], [%s]\n",inet_ntoa(tmpAddr.sin_addr), recvline);bzero(&tmpAddr, sizeof(tmpAddr));}if (n 

上一篇:游戏服务器被黑怎么解决?

下一篇:警惕网络风险,揭秘自动售卡密犯罪与寻找犯罪线索攻略