UDP 广播/组播

news/2024/5/18 14:00:43 标签: udp, 网络, 网络协议

广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址xxx.xxx.xxx.255,将消息发送到在同一广播网络上的每个主机,广播/组播只能用udp进行实现

 函数:int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_toptlen);

参数:
sockfd:要设置的套接字描述符。
level:选项定义的层次。或为特定协议的代码(如IPv4,IPv6,TCP,SCTP),或为通用套接字代码(SOL_SOCKET)。
optname:选项名。level对应的选项,一个level对应多个选项,不同选项对应不同功能。
optval:指向某个变量的指针,该变量是要设置新值的缓冲区。可以是一个结构体,也可以是普通变量
optlen:optval的长度。

关于optname的可选项,根据你需要的功能进行设置

当leve为SOL_SOCKET时,optname可以有以下选项(一部分)
SO_BROADCAST     允许发送广播数据            int
SO_DEBUG        允许调试                int
SO_LINGER        延迟关闭连接          struct linger
SO_OOBINLINE      带外数据放入正常数据流         int
SO_RCVBUF        接收缓冲区大小             int
SO_SNDBUF        发送缓冲区大小             int
SO_RCVLOWAT      接收缓冲区下限             int
SO_SNDLOWAT      发送缓冲区下限             int
SO_RCVTIMEO       接收超时           struct timeval
SO_SNDTIMEO       发送超时           struct timeval

流程:socket---setsockopt----sendto---close  值得注意的是 你的接收端必须和发送端保持一致的端口号,用广播地址进行发送,只要在同一局域网,且端口号一致的,都会收到发送端的消息,广播地址可以用ifconfig进行查看,接收方只需要接收就行了

出现的错误:发送端和接收端没有问题,但接收端死活接收不到消息,用准确的ip地址发就可以,用广播地址就是接收不到消息,后面我把接收端的ip地址改成:INADDR_ANY ,就可以

INADDR_ANY:表示本机上所有的ip地址,转换过来就是0.0.0.0,因为电脑不止一块网卡。多网卡情况下,ip地址也就多了

udp广播 发送端
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <unistd.h>


void main(int argc,char ** argv)
{
        if(argc != 3)
        {
                printf("argc error!\n");
                exit(-1);
        }

        int fd;
        char buf[128];
        struct sockaddr_in client;

        //1.socket

        fd = socket(AF_INET,SOCK_DGRAM,0);
        if(fd < 0)
        {
                perror("socket");
        }
        else
                printf("socket succeed!\n");

        //2.setsockopt

        int so_broadcast = 1;
        setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &so_broadcast, sizeof(so_broadcast));//SO_BROADCAST:为配置广播选项,
                                                                                                                          // so_broadcast :0,关闭广播;1:开
启广播


        client.sin_family = AF_INET;
        client.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&client.sin_addr);

        //3.sendto

        while(1)
        {
                memset(buf,'\0',sizeof(buf));
                printf("请输入您要发的消息:");
                gets(buf);

                if(!strncasecmp(buf,"quit",4))
                {
                        break;
                }

                sendto(fd,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client));
        }

        printf("客户端已退出-----\n");

        //4.close

        close(fd);
}

组播弥补了广播的不足,他是将想要收到消息的主机,通过组播地址加入到这个组播,只有加入了组播的主机,才会收到消息,组播地址范围:224.0.0.0 到 239.255.255.255

流程:socket--bind-- 加入多播组(结构体)---setsockopt(打开组播)---recvfrom---close

发送端只需要和接收端保持一致的端口号,用组播地址进行发送,加入到组播的主机就会收到消息

struct ip_mreq          
{ 
    struct in_addr imn_multiaddr; // 多播组 IP,
    struct in_addr imr_interface;   // 将谁的IP添加到多播组 
};

组播接收端

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SIZE 128


void main(int argc,char **argv)
{
        int fd;
        int bFlag;
        char buf[128];
        struct sockaddr_in server;
        struct sockaddr_in client;

        //1.socket

        fd = socket(AF_INET,SOCK_DGRAM,0);
        if(fd < 0)
        {
                printf("socket error!\n");
        }
        else
                printf("socket succeed!\n");

        //2.bind

        server.sin_family = AF_INET;
        server.sin_port = htons(8881);

        //inet_aton(argv[1],&server.sin_addr);

        server.sin_addr.s_addr = INADDR_ANY;

        bFlag = bind(fd,(struct sockaddr *)&server,sizeof(struct sockaddr_in));
        if(bFlag < 0)
        {
                printf("绑定失败\n");
        }
        else
                printf("绑定成功!\n");

        //3.加入多播组

        struct ip_mreq zuBo;//组播相关的结构体

        zuBo.imr_multiaddr.s_addr = inet_addr("224.0.0.1");//加入多播组 224.0.0.1~239.255.255.254
        zuBo.imr_interface.s_addr = INADDR_ANY;//本机加入多播组

        //4.设置网络属性 setsockopt

        int req = 1;

        setsockopt(fd,IPPROTO_IP,IP_DROP_MEMBERSHIP,&req,sizeof(req));


        //5.recvfrom

        while(1)
        {
                memset(buf,'\0',sizeof(buf));
                recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client));
                printf("来自组播:%s:%s\n",inet_ntoa(client.sin_addr),buf);
        }

        //6.close
}

 


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

相关文章

DevOps系列文章之 linux安装ftp

第一步 1、用root 进入系统 2、使用命令 rpm -qa|grep vsftpd 查看系统是否安装了ftp&#xff0c;若安装了vsftp&#xff0c;使用这个命令会在屏幕上显示vsftpd的版本 3、使用命令rpm -e vsftpd 即可卸载ftp 4、再使用rpm -qa|grep vsftpd 查看系统是否已删除ftp&#xff0…

day23 | 669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

目录&#xff1a; 解题及思路学习 669. 修剪二叉搜索树 链接&#xff1a;https://leetcode.cn/problems/trim-a-binary-search-tree/ 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[lo…

易混淆单词总结

英文中文frustrationn. 挫败&#xff0c;沮丧frustratevt. 挫败&#xff0c;使沮丧&#xff0c;阻止&#xff0c;挫败frustrated adj. 沮丧的 v. frustrate的过去和过分 frustrating adj. 令人沮丧的 v. frustrate的现分 infrastructuren. 基础设施infrastructuraladj. 基础设施…

Godot 4 源码分析 - 练手 - 和谐共生

今天看到一个微信视频&#xff0c;和谐共生&#xff0c;大概效果如下 https://live.csdn.net/v/306826 研究这么长时间的Godot&#xff0c;今天试试能否实现上述效果 粗看一下&#xff0c;这个效果实现分几步&#xff1a; 1. 画圆&#xff0c;并确定多个圆的位置规律 2. 动…

Nginx 的学习与实战【二】

三、配置文件 nginx.conf 配置文件&#xff1a; user nginx; worker_processes auto;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }http {include /etc/nginx/mime.types;default_type applicat…

你不知道的HTML属性,让你的网页更加响应式

前言 当我们谈论 HTML 时&#xff0c;通常会想到一些常见的属性&#xff0c;如 class、id、href 等等。但是&#xff0c;HTML 还有许多你可能从未听说过的属性&#xff0c;这些属性可以让你的网页更加丰富多彩。在本文中&#xff0c;我将介绍一些你可能不知道的 HTML 属性&…

ModuleNotFoundError: No module named “pbxproj“

项目中有个打包脚本需要用到pbxproj这个python库&#xff0c;这里也正常通过pip安装了pbxproj&#xff0c;但是实际上执行脚本的时候报了 ModuleNotFoundError: No module named pbxproj 那么出现这个问题第一反应是环境变量添加错了&#xff0c;于是打开自己的.zshrc文件&am…

【MySQL 】:测试数据准备、SQL语句规范与基本操作

前言 欢迎来到小K的MySQL专栏&#xff0c;本节将为大家准备MySQL测试数据、以及带来SQL语句规范、数据库的基本操作的详细讲解~✨文末送书&#xff0c;小K赠书活动第二期 目录 前言一、准备测试数据二、SQL语句规范三、数据库的基本操作四、总结&#xff1a;文末赠书 一、准备测…