#include <stdio.h> #include <stdlib.h> #include <netdb.h> #include <string.h> #include "Utility.h" //多播发送者 使用例子 ./Sender 224.0.0.2 8888 hehe你好 5 int main(int argc, char** argv) { if(argc<4||argc>5) { //接收多播地址和端口 DieWithUserMessage("param","<multicast address> <port> <send string><TTL>"); } char * multicastIPString=argv[1]; char* service=argv[2]; char* sendString=argv[3]; size_t senStringLen=strlen(sendString); if(senStringLen>MAXSTRINGLENGTH) { DieWithUserMessage("string too long ",sendString); } //生命周期 int multicastTTL=(argc==5)?atoi(argv[4]):1; //配置想要的地址结构 struct addrinfo addr_criteria; memset(&addr_criteria,0,sizeof(addr_criteria)); addr_criteria.ai_socktype=SOCK_DGRAM; addr_criteria.ai_family=AF_UNSPEC; addr_criteria.ai_protocol=IPPROTO_UDP; // addr_criteria.ai_flags |=AI_NUMERICHOST; struct addrinfo*multicastAddr; //获取地址信息 int ret=getaddrinfo(multicastIPString,service,&addr_criteria,&multicastAddr); if(ret!=0) DieWithUserMessage("getaddrinfo() failed!",gai_strerror(ret)); //建立socket int sock=socket(multicastAddr->ai_family,multicastAddr->ai_socktype,multicastAddr->ai_protocol); if(sock<0) DieWithSystemMessage("socket() failed!"); if(multicastAddr->ai_family==AF_INET6) { //如果是ip6,设置socket,允许发送多播和设置生命周期 if(setsockopt(sock,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,&multicastTTL,sizeof(multicastTTL))<0) { DieWithSystemMessage("setsockopt() failed!"); } }else if(multicastAddr->ai_family=AF_INET) { //如果时ip4,设置socket,允许发送多播和设置生命周期 u_char mcTTL=(u_char)multicastTTL; if(setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,&mcTTL,sizeof(mcTTL))<0) { DieWithSystemMessage("setsockopt() failed!"); } }else{ DieWithUserMessage("unable to set TTL","invalid address family"); } printf("multicastIPString:%s service:%s sendString:%s \n",multicastIPString,service,sendString); for(;;) { //循环发送数据 ssize_t numBytes=sendto(sock,sendString,senStringLen,0,multicastAddr->ai_addr,multicastAddr->ai_addrlen); if(numBytes<0) { DieWithSystemMessage("sendto() failed!"); }else if(numBytes!=senStringLen) { DieWithUserMessage("sendto()","sent unexpected number of bytes"); } sleep(3); } return (EXIT_SUCCESS); }
#include <stdio.h> #include <stdlib.h> #include <netdb.h> #include <string.h> #include "Utility.h" //多播接收 使用例子 ./sender 224.0.0.2 8888 hehae 5 int main(int argc, char** argv) { //参数判断 if (argc != 3) DieWithUserMessage("param", "<multicast address> <port>"); char * multicastAddrString = argv[1]; char* service = argv[2]; //配置想要的地址结构 struct addrinfo addr_criteria; memset(&addr_criteria, 0, sizeof (addr_criteria)); addr_criteria.ai_family = AF_UNSPEC; addr_criteria.ai_socktype = SOCK_DGRAM; addr_criteria.ai_protocol = IPPROTO_UDP; addr_criteria.ai_flags = AI_NUMERICHOST; struct addrinfo *multicastAddr; //获取多播地址 int ret = getaddrinfo(multicastAddrString, service, &addr_criteria, &multicastAddr); if (ret != 0) DieWithUserMessage("getaddrinfo() failed!", gai_strerror(ret)); //建立sockset int sock = socket(multicastAddr->ai_family, multicastAddr->ai_socktype, multicastAddr->ai_protocol); if (sock < 0) DieWithSystemMessage("socket() failed!"); //绑定端口 if (bind(sock, multicastAddr->ai_addr, multicastAddr->ai_addrlen) < 0) { DieWithSystemMessage("bind() failed!"); } if (multicastAddr->ai_family == AF_INET6) { //如果时IPV6,则加入IPV6多播组 struct ipv6_mreq joinRequest; //拷贝 memcpy(&joinRequest.ipv6mr_multiaddr, &((struct sockaddr_in6*) multicastAddr->ai_addr)->sin6_addr, sizeof (struct in6_addr)); joinRequest.ipv6mr_interface = 0; puts("Joining ipv6 mulicast group.."); //设置socket信息 if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &joinRequest, sizeof (joinRequest)) < 0) { DieWithSystemMessage("setsockopt() failed!"); } } else if (multicastAddr->ai_family == AF_INET) { //如果时ipv4,则加入多播组 struct ip_mreq ip_joinRequest; ip_joinRequest.imr_multiaddr = ((struct sockaddr_in *) multicastAddr->ai_addr)->sin_addr; ip_joinRequest.imr_interface.s_addr = 0; printf("Joining ipv4 multicast group...\n"); //设置socket信息 if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ip_joinRequest, sizeof (ip_joinRequest)) < 0) { DieWithSystemMessage("setsockopt() failed!"); } } else { DieWithSystemMessage("unknown address family!"); } //清理 freeaddrinfo(multicastAddr); char* recvString[MAXSTRINGLENGTH + 1]; //接收数据 int recvStringLen = recvfrom(sock, recvString, MAXSTRINGLENGTH, 0, NULL,0); if (recvStringLen < 0) DieWithSystemMessage("recvfrom() failed!"); recvString[recvStringLen] = '\0'; printf("Received:%s\n", recvString); close(sock); return (EXIT_SUCCESS); }