首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

一个关于linux多播的有关问题

2012-03-08 
一个关于linux多播的问题以下是linux多播的测试代码,分为服务器端和客户端,问题是客户端收不到任信息,我想

一个关于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

热点排行