UDP多播/组播
通过UDP实现局域网多播、组播
头文件:proto.h
#ifndef __PROTO_H__
#define __PROTO_H__
#define BORDCAST "224.2.2.2" //定义组播IP地址
#define PORT "10001" //组播端口
#define NAMESIZE 11
struct student_st //自定义传输结构体
{
uint8_t name[NAMESIZE];
uint32_t math;
uint32_t chinese;
}__attribute__((packed)); //要求字节不对齐
#endif
接收端:rcver.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h>
#include "proto.h"
#define IPSIZE 40
int main()
{
int lsockfd;
int ret;
socklen_t llenth,rlenth;
struct sockaddr_in ldata,rdata;
ssize_t lenth;
struct student_st stu;
char ipbuff[IPSIZE];
lsockfd = socket(AF_INET,SOCK_DGRAM,0); //创建socket
if(lsockfd <0)
{
perror("socket()");
exit(1);
}
struct ip_mreqn val; //初始化结构体
inet_pton(AF_INET,BORDCAST,&val.imr_multiaddr.s_addr);
inet_pton(AF_INET,"0.0.0.0",&val.imr_address.s_addr);
val.imr_ifindex = if_nametoindex("eth0");
ret = setsockopt(lsockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&val,sizeof(val)); //设置socket属性 加入多播组
if(ret <0)
{
perror("setsockopt()");
exit(1);
}
ldata.sin_family = AF_INET; //初始化结构体
ldata.sin_port =htons(atoi(PORT));
llenth = sizeof(ldata);
inet_pton(AF_INET,"0.0.0.0",&ldata.sin_addr.s_addr);
ret = bind(lsockfd,(void *)&ldata,llenth); //绑定IP及端口
if(ret <0)
{
perror("bind()");
exit(1);
}
while(1)
{
rlenth = sizeof(rdata);
lenth = recvfrom(lsockfd,&stu,sizeof(stu),0,(void *)&rdata,&rlenth); //接收数据
if(lenth <0)
{
perror("recvfrom()");
exit(1);
}
inet_ntop(AF_INET,&rdata.sin_addr.s_addr,ipbuff,IPSIZE);
printf("IP:%s PORT:%d\n",ipbuff,ntohs(rdata.sin_port));
printf("name:%s math:%d chinese:%d\n",stu.name,ntohl(stu.math),ntohl(stu.chinese)); //输出
}
close(lsockfd);
exit(0);
}
发送端:sender.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <net/if.h>
#include <unistd.h>
#include "proto.h"
int main(int argc,char **argv)
{
int lsockfd;
struct student_st stu;
struct sockaddr_in rsock;
ssize_t ret;
lsockfd = socket(AF_INET,SOCK_DGRAM,0); //创建socket
if(lsockfd <0)
{
perror("lsockfd()");
exit(1);
}
struct ip_mreqn val; //初始化结构体
inet_pton(AF_INET,BORDCAST,&val.imr_multiaddr.s_addr);
inet_pton(AF_INET,"0.0.0.0",&val.imr_address.s_addr);
val.imr_ifindex = if_nametoindex("eth0");
ret = setsockopt(lsockfd,IPPROTO_IP,IP_MULTICAST_IF,&val,sizeof(val)); //设置socket属性 创建多播组
if(ret <0)
{
perror("setsockopt()");
exit(1);
}
strcpy(stu.name,"Alin"); //初始化结构体
stu.math =htonl(rand()%100);
stu.chinese = htonl(rand()%100);
rsock.sin_family = AF_INET;
rsock.sin_port = htons(atoi(PORT));
inet_pton(AF_INET,BORDCAST,&rsock.sin_addr.s_addr);
ret = sendto(lsockfd,&stu,sizeof(stu),0,(void *)&rsock,sizeof(rsock)); //发送数据
if(ret <0)
{
perror("sendto");
exit(1);
}
close(lsockfd);
exit(0);
}
编译文件:Makefile
all:rcver sender
rcver:rcver.o
$(CC) $^ -o $@
sender:sender.o
$(CC) $^ -o $@
clean:
$(RM) *.o rcver sender
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现