首页 > 编程语言 >【网络编程开发】14.广播和组播

【网络编程开发】14.广播和组播

时间:2024-06-15 20:04:21浏览次数:29  
标签:组播 Addr peeraddr 编程 struct argv fd include 14

14.广播和组播

什么是广播

  • 数据包发送方式只有一个接受方,称为单播
  • 如果同时发给局域网中的所有主机,称为广播
  • 只有用户数据报(使用UDP协议)套接字才能广播

广播地址

  • 一个网络内主机号全为1的IP地址为广播地址
  • 发到该地址的数据包被所有的主机接收
  • 255.255.255.255在所有网段中都代表广播地址

在这里插入图片描述

实现广播

ifconfig 命令 查看广播ip

在这里插入图片描述

  1. IP地址(inet addr):192.168.19.139
  2. 广播地址(Bcast):192.168.19.255
  3. 子网掩码(Mask):255.255.255.0

设置允许广播

/*允许广播*/
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

sender.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string.h>

#define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;

int main(int argc, char *argv[])
{
	int fd = -1;
	Addr_in peeraddr;
	socklen_t peerlen = sizeof(peeraddr);
	char buf[BUFSIZ] = {};
	/*参数检查*/
	if(argc < 3){
		fprintf(stderr, "%s<multiaddr><port>", argv[0]);
		exit(EXIT_FAILURE);
	}
	/*创建套接字*/
	if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
		ErrExit("socket");

	/*允许广播*/
	int on = 1;
	setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

	/*设置通信结构体*/
	peeraddr.sin_family = AF_INET;
	peeraddr.sin_port = htons(atoi(argv[2]));
	if(!inet_aton(argv[1], &peeraddr.sin_addr) ){
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}
	while(1){
		fgets(buf, BUFSIZ, stdin);
		sendto(fd, buf, strlen(buf)+1, 0, (Addr *)&peeraddr, peerlen);
	}
	return 0;
}

receive.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <strings.h>

#define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;

int main(int argc, char *argv[])
{
	int fd = -1;
	Addr_in myaddr, peeraddr;
	socklen_t peerlen = sizeof(peeraddr);
	char buf[BUFSIZ] = {};
	/*参数检查*/
	if(argc < 3){
		fprintf(stderr, "%s<addr><port>", argv[0]);
		exit(EXIT_FAILURE);
	}
	/*创建套接字*/
	if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
			ErrExit("socket");
	/*设置通信结构体*/
	myaddr.sin_family = AF_INET;
	myaddr.sin_port = htons(atoi(argv[2]));
	if(!inet_aton(argv[1], &myaddr.sin_addr) ){
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}
	/*绑定通信结构体*/
	if( bind(fd, (Addr *)&myaddr, sizeof(Addr_in)) )
		ErrExit("bind");
	while(1){
		recvfrom(fd, buf, BUFSIZ, 0, (Addr *)&peeraddr, &peerlen);
		printf("[%s:%d]%s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);
	}
	return 0;
}
  1. 启动接收程序:
    • ./receiver 0 8080
  2. 启动发送程序:
    • ./sender 192.168.19.255 8080
  3. 开始发送数据

在这里插入图片描述

通信成功

什么是组播(多播)

  • 在 IP 多播数据报的目的地址需要写入多播组的标识符。

  • 多播组的标识符就是 IP 地址中的 D 类地址(多播地址)

    • 地址范围:224.0.0.0 ~ 239.255.255.255
  • 每一个 D 类地址标志一个多播组。

  • 多播地址只能用于目的地址,不能用于源地址。

组播实现步骤

  1. 创建用户数据报套接字

  2. 加入多播组

  3. 绑定组播IP地址和端口

  4. 等待接收数据

组播设置

方法1

使用结构体struct ip_mreqn

struct ip_mreqn {
    struct in_addr imr_multiaddr;  /*IP 组播组地址*/
    struct in_addr imr_address;   /*本地接口的IP地址*/
    int imr_ifindex;   /*本地网卡的编号*/
}

创建完套接字后,调用设置

if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0){
perror("setsockopt");
exit(0);
}

方法2

使用结构体struct ip_mreq

struct ip_mreq {
    struct in_addr imr_multiaddr;  /*IP 组播组地址*/
    struct in_addr imr_interface;   /*本地接口的IP地址*/
}

创建完套接字后,调用设置

if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0){
perror("setsockopt");
exit(0);
}

组播实现

receive.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <strings.h>

#define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;

int main(int argc, char *argv[])
{
	int fd = -1;
	Addr_in myaddr, peeraddr;
	socklen_t peerlen = sizeof(peeraddr);
	struct ip_mreqn mreq;
	char buf[BUFSIZ] = {};
	/*参数检查*/
	if(argc < 3){
		fprintf(stderr, "%s<addr><port>", argv[0]);
		exit(EXIT_FAILURE);
	}
	/*创建套接字*/
	if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
			ErrExit("socket");
	/*加入多播组*/
	bzero(&mreq, sizeof(mreq) );
	if(!inet_aton(argv[1], &mreq.imr_multiaddr) ){
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}
	if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0){
		perror("setsockopt");
		exit(0);
	}

	/*设置通信结构体*/
	myaddr.sin_family = AF_INET;
	myaddr.sin_port = htons(atoi(argv[2]));
	if(!inet_aton(argv[1], &myaddr.sin_addr) ){
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}
	/*绑定通信结构体*/
	if( bind(fd, (Addr *)&myaddr, sizeof(Addr_in)) )
		ErrExit("bind");
	while(1){
		recvfrom(fd, buf, BUFSIZ, 0, (Addr *)&peeraddr, &peerlen);
		printf("[%s:%d]%s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);
	}
	return 0;
}

sender.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string.h>

#define ErrExit(msg) do {perror(msg); exit(EXIT_FAILURE);} while(0)
typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;

int main(int argc, char *argv[])
{
	int fd = -1;
	Addr_in peeraddr;
	socklen_t peerlen = sizeof(peeraddr);
	char buf[BUFSIZ] = {};
	/*参数检查*/
	if(argc < 3){
		fprintf(stderr, "%s<multiaddr><port>", argv[0]);
		exit(EXIT_FAILURE);
	}
	/*创建套接字*/
	if( (fd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0)
		ErrExit("socket");

	/*设置通信结构体*/
	peeraddr.sin_family = AF_INET;
	peeraddr.sin_port = htons(atoi(argv[2]));
	if(!inet_aton(argv[1], &peeraddr.sin_addr) ){
		fprintf(stderr, "Invalid address\n");
		exit(EXIT_FAILURE);
	}
	while(1){
		fgets(buf, BUFSIZ, stdin);
		sendto(fd, buf, strlen(buf)+1, 0, (Addr *)&peeraddr, peerlen);
	}
	return 0;
}

使用在 224.0.0.0 ~ 239.255.255.255 范围内的地址

  1. 启动接收端
    • ./receiver 239.10.10.2 8080
  2. 启动发送段
    • ./sender 239.10.10.2 8080
  3. 发送数据

在这里插入图片描述

标签:组播,Addr,peeraddr,编程,struct,argv,fd,include,14
From: https://blog.csdn.net/2201_75563094/article/details/139613900

相关文章

  • 【网络编程开发】16.域名解析与http服务器实现原理
    16.域名解析与http服务器实现原理gethostbyname函数原型:#include<netdb.h>structhostent*gethostbyname(constchar*hostname);功能:获取主机名对应的IP地址参数:hostname:要查询的主机名。返回值:成功时,返回一个指向hostent结构的指针。失败时,返回NULL。......
  • 完美解决“由于找不到msvcp140.dll,vcruntime140_1.dll,msvcp100.dll,msvcr120.dll等导致
    成功解决问题:由于找不到msvcp140.dll,vcruntime140_1.dll,msvcp100.dll,msvcr120.dll,mfc140u.dll,mfc140u.dll等导致的无法继续执行代码。重新安装程序可能会解决此问题。......
  • 持续总结中!2024年面试必问 20 道并发编程面试题(七)
    上一篇地址:持续总结中!2024年面试必问20道并发编程面试题(六)-CSDN博客十三、请解释什么是生产者-消费者问题。生产者-消费者问题(Producer-ConsumerProblem)是计算机科学和操作系统中的一个经典同步问题。这个问题描述了两种不同的进程或线程:生产者(Producer)和消费者(Consumer),它......
  • 持续总结中!2024年面试必问 20 道并发编程面试题(八)
    上一篇地址:持续总结中!2024年面试必问20道并发编程面试题(七)-CSDN博客十五、请解释什么是阻塞队列(BlockingQueue)。阻塞队列(BlockingQueue)是一种特殊的队列,它是Java并发集合的一部分,用于在多线程环境中进行线程间通信。当生产者线程(Producer)尝试将元素放入队列时,如果队列已......
  • 《并发编程系列01》从底层源码剖析AQS的来龙去脉!(通俗易懂)
    前言本文是作者的第一篇文章,目的就是可以分享自己个人的一些技术上的心得体会以及找寻志同道合的人来共同讨论技术。个人学习难免会有一些理解上的错误,所以写博客也是为了记录和反思自己的学习过程,进一步加深对技术的理解和掌握。希望通过这篇博客,能够帮助到一些和我一样......
  • 整理好了!2024年最常见 20 道并发编程面试题(七)
    上一篇地址:整理好了!2024年最常见20道并发编程面试题(六)-CSDN博客十三、请描述什么是生产者-消费者问题以及如何解决它。生产者-消费者问题,也称为有限缓冲问题,是计算机科学和操作系统中的一个经典同步问题。这个问题描述了两个进程组:生产者(Producer)和消费者(Consumer),它们共享......
  • 17岁中专女生勇夺2024阿里全球数学赛12名好成绩,今天,站在程序员的视角,我们来聊聊数学对
    大家好,我是程序员陶朱公,一个认真生活,总想超越自己的程序员。前言相信这两天,大家都刷屏到了一个比较热度的新闻——17岁中专女生在今年这届阿里举办的全球数赛中,勇夺第12名的好成绩。↓↓↓看到这里,可能有小伙伴会觉得有点疑惑:又不是第一名,不明白第12名的她,为什么会引起社会......
  • 高并发编程的好处和注意事项
    高并发编程的意义、好处和注意事项由于多核多线程的CPU的诞生,多线程、高并发的编程越来越受重视和关注。多线程可以给程序带来如下好处。(1)充分利用CPU的资源从上面的CPU的介绍,可以看的出来,现在市面上没有CPU的内核不使用多线程并发机制的,特别是服务器还不止一个......
  • 编程语言
    编程语言机器语言机器语言是用二进制代码表示的语言,是计算机唯一可以直接识别和执行的语言,它具有计算机可以直接执行、简洁、运算速度快等优点,但它的直观性差,非常容易出错,程序的检查和调试都比较困难,此外对机器的依赖型也很强。汇编语言汇编语言是面向机器的程序设计语言,它是......
  • 超14%的年轻人正通过AIGC赚钱!!!
    AIGC:生成式人工智能。这是当下最热的名词。自ChatGPT横空出世,新技术引发的震动持续至今。Al展现出的理解现实世界、颠覆式生产能力足够震撼——根据文字生成符合现实世界物理规律视频的Sora,能够一键作词编曲的Suno…每个相关新产品的发布都堪称里程碑式事件,让这一波技术......