Linux 下UDP组播


Linux系统下UDP组播客户端程序如下:
int init_multicast_socket(void)
{
 int err = -1;
 struct ip_mreq mreq;
 struct sockaddr_in recvAddr;

    /* 建立socket连接*/
 if((sockListen = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
 {
   perror("socket()");
   return -1;
 }
 else
   dbg_out("sockListen = %d\n", sockListen);

 int set = 1;
 if(setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(int)) < 0)
  perror("Setting SO_REUSEADDR error");
 else
   dbg_out("Setting SO_REUSEADDR...OK.\n");     

 memset(&recvAddr, 0, sizeof(struct sockaddr_in));
 recvAddr.sin_family = AF_INET;
 recvAddr.sin_port = htons(6789);
 recvAddr.sin_addr.s_addr = INADDR_ANY;

 /*必须绑定,否则无法监听*/
 if(bind(sockListen, (struct sockaddr *)&recvAddr, sizeof(struct sockaddr)) == -1)
    perror("bind fail\n");
  else

  dbg_out("bind OK ...\n");

   /* 填充多播结构体 */
        mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/
 /* 这里需要注意 imr_interface.s_addr 必须是一个ip地址不能是INADDR_ANY否则收不到数据*/
       mreq.imr_interface.s_addr = inet_addr("192.168.0.152"); //htonl(INADDR_ANY); /*网络接口为默认*/            
      
      /*将本机加入多播组*/                                      
     err = setsockopt(sockListen, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
     if (err < 0)
         perror("setsockopt():IP_ADD_MEMBERSHIP");
     else
     dbg_out("join in group cast OK...\n");

      return (0);
}
注意:上面的结构体变量 imr_interface.s_addr 必须是一个IP地址(本机的IP)不能是INADDR_ANY,否则收不到数据
上面的inet_addr(" ")函数存在潜在的问题,建议使用比较新的兼容ipv6的函数,可以将上面的改成如下:
将字符串转换成网络二进制数
inet_pton(AF_INET, MCAST_ADDR, &mreq.imr_multiaddr);

inet_pton(AF_INET, "192.168.0.152", &mreq.imr_interface);

你可能感兴趣的:(Technology)