linux c sockset之多播

#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);
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值