socket接收组播报文主要有两个操作:
1、将组播地址bind到socket句柄上
2、根据IGMP协议通过IP_ADD_MEMBERSHIP向外发出JION帧
具体实例代码如下:
udp_group_server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int ret;
char recv_buf[1024];
int length=0;
struct sockaddr_in sender;
int sender_len = sizeof(sender);
char group[16]="224.0.0.88";
struct sockaddr_in local_addr;
struct ip_mreq mreq;
int sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
{
printf("socket failed.\n");
return 2;
}
memset(&local_addr,0,sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(8888);
ret = bind(sock,(struct sockaddr *)&local_addr,sizeof(local_addr));
if(ret<0)
{
perror("bind failed.\n");
return 3;
}
mreq.imr_multiaddr.s_addr = inet_addr(group);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
/*
* IP_ADD_MEMBERSHIP will send jion frame to the network device for joining the group network.
* Then the network device will send multi-frames to the client.
*/
ret=setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq));
if(ret<0)
{
printf("setsockopt failed.\n");
return 4;
}else{
printf("setsockopt success\n");
}
while(1)
{
memset(recv_buf,0,sizeof(recv_buf));
length = recvfrom(sock,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&sender,&sender_len);
recv_buf[length]='\0';
printf("receive buffer: %s\n", recv_buf);
}
close(sock);
return 0;
}
udp_group_client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char group_addr[16]="224.0.0.88";
char buf[1024] = "This is a group udp.";
int length=strlen(buf);
struct sockaddr_in remote_addr;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock<0)
{
printf("socket failed.\n");
return 2;
}
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr(group_addr);
remote_addr.sin_port = htons(8888);
length = sendto(sock,buf,strlen(buf),0,(struct sockaddr *)&remote_addr,sizeof(remote_addr));;
printf("send %s\n", buf);
close(sock);
return 0;
}
Makefile:
all:udp_group_server udp_group_client
udp_group_server:
gcc udp_group_server.c -o udp_group_server
udp_group_client:
gcc udp_group_client.c -o udp_group_client
clean:
rm -rf udp_group_client udp_group_server
编译并运行:
# make
gcc udp_group_server.c -o udp_group_server
gcc udp_group_client.c -o udp_group_client
# ./udp_group_server &
[1] 97800
# setsockopt success
# ./udp_group_client
send This is a group udp.
receive buffer: This is a group udp.