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