LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1040|回复: 1

2.6以上内核下的组播问题

[复制链接]
发表于 2005-11-7 17:58:41 | 显示全部楼层 |阅读模式
因为着急,所以在这里也发一遍,还请管理员谅解。

各位好,目前遇到一个2.6内核下的组播问题要请教一下。
环境:
支持IGMPv2和IGMP snooping的交换机,
一台组播服务器使用2.4.20内核,Redhat9
一台PC客户端使用2.6.8内核,Fedora core 3
服务器和客户端上运行后面给出的组播示例程序,程序从网上找的,编译都没有问题。

症状:
客户端无法接收服务器下来的组播数据,经过调查认为是Fedora core 3目前支持的是IGMPv3,
由于交换机不支持IGMPv3,所以加入组播组的消息被忽略,这点通过在客户端上运行iptraf可以
看到,发送的消息是到IGMPv3的224.0.0.22而不是IGMPv2里面的224.0.0.2。
基于此,根据网上查阅的信息,强制让Fedora core 3使用IGMPv2,
#/sbin/sysctl -w net.ipv4.conf.eth1.force_igmp_version=2
重新运行客户端组播接收程序和iptraf,现在发现确实申请加入组播地址224.0.0.2,
而且在iptraf里也看到了组播服务器下来的组播数据,但是客户端的程序却无法接收上来。

分析:
iptraf可以看到组播服务器下来的数据说明强制让Fedora core 3使用IGMPv2发生了效果,
但是为何客户端应用层上还是无法接收呢?
此问题已经困扰我好几天了,不知道版上有没有专家可以解答?非常感谢!

/*

multicast.c

The following program sends or receives multicast packets. If invoked
with one argument, it sends a packet containing the current time to an
arbitrarily chosen multicast group and UDP port. If invoked with no
arguments, it receives and prints these packets. Start it as a sender on
just one host and as a receiver on all the other hosts

*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>

#define EXAMPLE_PORT 6000
#define EXAMPLE_GROUP "239.0.0.1"

main(int argc)
{
   struct sockaddr_in addr;
   int addrlen, sock, cnt;
   struct ip_mreq mreq;
   char message[50];

   /* set up socket */
   sock = socket(AF_INET, SOCK_DGRAM, 0);
   if (sock < 0) {
     perror("socket");
     exit(1);
   }
   bzero((char *)&addr, sizeof(addr));
   addr.sin_family = AF_INET;
   addr.sin_addr.s_addr = htonl(INADDR_ANY);
   addr.sin_port = htons(EXAMPLE_PORT);
   addrlen = sizeof(addr);

   if (argc > 1) {
      /* send */
      addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP);
      while (1) {
         time_t t = time(0);
         sprintf(message, "time is %-24.24s", ctime(&t));
         printf("sending: %s\n", message);
         cnt = sendto(sock, message, sizeof(message), 0,
                      (struct sockaddr *) &addr, addrlen);
         if (cnt < 0) {
            perror("sendto");
            exit(1);
         }
         sleep(5);
      }
   } else {

      /* receive */
      if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        
         perror("bind");
         exit(1);
      }   
      mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP);         
      mreq.imr_interface.s_addr = htonl(INADDR_ANY);         
      if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                     &mreq, sizeof(mreq)) < 0) {
         perror("setsockopt mreq");
         exit(1);
      }         
      while (1) {
         cnt = recvfrom(sock, message, sizeof(message), 0,
                        (struct sockaddr *) &addr, &addrlen);
         if (cnt < 0) {
            perror("recvfrom");
            exit(1);
         } else if (cnt == 0) {
            break;
         }
         printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message);
        }
    }
}
发表于 2005-11-7 18:43:53 | 显示全部楼层
是不是UDP端口的问题, 把bind去掉试试.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表