一个关于linux多播的问题
以下是linux多播的测试代码,分为服务器端和客户端,问题是客户端收不到任信息,我想问的是在用多播之前还需不需要进行一些相关的网络配置,我不知道到底是配置的问题还是程序的问题
客户端:
#define MCAST_PORT 8888
#define MCAST_ADDR "224.0.0.88" /*一个局部连接多播地址,路由器不进行转发*/
#define MCAST_INTERVAL 5 /*发送间隔时间*/
#define BUFF_SIZE 256 /*接收缓冲区大小*/
int main(int argc, char*argv[])
{
int s; /*套接字文件描述符*/
struct sockaddr_in local_addr; /*本地地址*/
int err = -1;
s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
if (s == -1) {
perror("socket()");
return -1;
}
/*初始化地址*/
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(MCAST_PORT);
/*绑定socket*/
err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
if(err < 0) {
perror("bind()");
return -2;
}
/*设置回环许可*/
int loop = 1;
err = setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
if(err < 0) {
perror("setsockopt():IP_MULTICAST_LOOP");
return -3;
}
struct ip_mreq mreq; /*加入广播组*/
mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*广播地址*/
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*网络接口为默认*/
/*将本机加入广播组*/
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*网络接口为默认*/
/*将本机加入广播组*/
err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
if (err < 0) {
perror("setsockopt():IP_ADD_MEMBERSHIP");
return -4;
}
int times = 0;
int addr_len = 0;
char buff[BUFF_SIZE];
int n = 0;
/*循环接收广播组的消息,5次后退出*/
for(times = 0;times<5;times++)
{
addr_len = sizeof(local_addr);
memset(buff, 0, BUFF_SIZE); /*清空接收缓冲区*/
/*接收数据*/
n = recvfrom(s, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr, &addr_len);
if( n== -1) {
perror("recvfrom()");
}
/*打印信息*/
printf("Recv %dst message from server:%s\n", times, buff);
sleep(MCAST_INTERVAL);
}
/*退出广播组*/
err = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq));
close(s);
return 0;
}
下面是服务器端代码:
#define MCAST_PORT 8888
#define MCAST_ADDR "224.0.0.88"
#define MCAST_DATA "BROADCAST TEST DATA"
#define MCAST_INTERVAL 1
int main(int argc, char **argv) {
int s;
struct sockaddr_in mcast_addr;
s = socket(AF_INET, SOCK_DGRAM, 0);
if(s == -1) {
perror("socket()");
return -1;
}
memset(&mcast_addr, 0, sizeof(mcast_addr));
mcast_addr.sin_family = AF_INET;
mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
mcast_addr.sin_port = htons(MCAST_PORT);
while(1) {
int n = sendto(s, MCAST_DATA, sizeof(MCAST_DATA), 0,
(struct sockaddr*)&mcast_addr, strlen(struct sockaddr) + 1);
if(n < 0) {
perror("sendto()");
return -2;
}
printf("%s\n", "send successful");
sleep(MCAST_INTERVAL);
}
return 0;
}
~
[解决办法]
(struct sockaddr*)&mcast_addr, strlen(struct sockaddr) + 1);
这一行代码中对结构体“struct sockaddr”用“strlen”测字符长度应该是有问题的。
另,大多linux发行版本关闭对多播功能的支持,为了在Linux系统使用多播套接口,需要从新配置和编译Linux内核。
[解决办法]
使用wireshark抓下包,看是否服务器发出来的包是正确的组播包。
[解决办法]
多播测试,如果是在局域网,两个PC连接到一个交换机上的时候,网络应该没问题。
另外,注意,接收多播的那台机器的网卡必须打开"杂混"模式。IFF_PROMISC