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