一台ANDROID4.0的真机,不是模拟器,建立接收组播数据用的套接字,bind,setsockopt等等在代码层面上一切正常,但一直没有发现机器发出IGMP包
近乎同样的代码,在LINUX台式机上跑着一切正常,也的确是发出了IGMP的加入组播组的数据包。有人说这个问题在于系统内核,但真机上是可以向组播组发包的,不知道这样是不是就可以判定内核是支持组播的。busybox ifconfig eth0的结果是"UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1",不知道这样是不是也可以判定内核支持组播。网上也有好多说法是对诸如对 ip_forward及icmp_echo_ignore_broadcasts的设置,本人不甚了解,乱试一通,无果。各位大侠倘若哪怕有些许想法,也请不吝赐教。源码奉上:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <map>
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h>
#include <errno.h>#define GroupIP "224.7.7.7" //要加入的组播组
#define GroupPort 7777 //组播监听端口int main(void)
{
int s; //套接字
struct sockaddr_in srv; //组播地址
struct ip_mreq mreq; //这儿也用ip_mreqn测试过,没有新发现。 //建立套接字
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
printf("socket failed");
return false;
} {//绑定IP
memset(&srv,0, sizeof(srv));
srv.sin_family = AF_INET;
srv.sin_port = htons(GroupPort);
if (inet_aton(GroupIP, &srv.sin_addr) < 0)
{
printf("inet_aton failed");
return false;
}
if (bind(s, (struct sockaddr *) &srv, sizeof(srv)) < 0)
{
close(s);
printf("bind failed");
return false;
}
} {//加入组播组
if (inet_aton(GroupIP, &mreq.imr_multiaddr) < 0)
{
close(s);
printf("inet_aton failed");
return false;
}
inet_aton("192.168.15.55", &mreq.imr_interface);//"192.168.15.55"是本机IP,如果指定INADDR_ANY需要配置路由。 unsigned char ttl=200;
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); int errorSetSockOpt=setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
if ( errorSetSockOpt< 0)
{
close(s);
printf("join failed:%d:%d",errorSetSockOpt,errno);
return false;
}
} {//等待一段时间,传说立即退出的话,即便正常的系统也不会发出IGMP
sleep(1);
} {//退出组播组
if ((setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void*) &mreq, sizeof(mreq))) < 0)
{
printf("drop failed:%d",errno); 
close(s);
return false;
}else
{
printf("drop successed"); 
}
}
close(s);
return true;
}androidsocket组播   无法加入

解决方案 »

  1.   

    who can help me ,please
      

  2.   

    conclusion?
    if CONFIG_IP_MULTICAST disabled,setsockopt will succeed,but none igmp will be sent.
    however,i have to send igmp manually...........
    what a broken heart........references:
    http://code.google.com/p/android/issues/detail?id=2917
    https://groups.google.com/forum/?fromgroups#!topic/android-developers/BTwBRDvHBds
    http://stackoverflow.com/questions/3179710/how-to-receive-multicast-packets-on-android
    http://www.programmingmobile.com/2012/01/multicast-and-android-big-headache.html
    https://sites.google.com/site/miclinuxcorner/technology/multicast-routing
    http://unix.stackexchange.com/questions/25872/how-can-i-know-if-ip-multicast-is-enabled
    http://cafbit.com/entry/testing_multicast_support_on_android
    http://code.google.com/p/android/issues/detail?id=51195
      

  3.   

    下面是可行的android客户端代码,现在的问题是PC给android手机发,丢包很严重,我们可以一起学习,交流,解决问题,我都搞了俩个礼拜了/**************************************************************************************************************
     **文件:client.c
     **编写者:feixiao
     **编写日期:2013年3月27日
     **简要描述:多播客户端
     **修改日期:
     **注:加入多播组,用于接收服务器发送的信息
     **************************************************************************************************************/
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <errno.h>
    #include <stdio.h>#define  BUFFER_SIZE 1024  // 每次传送的buffer大小
    /***** 主函数 *************************************************************************************************/
    int main(void)
    {
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    char bReuse = 1;
    struct sockaddr_in si;
    struct ip_mreq mcast;
    FILE* pFile = NULL;
    char* pFilePath = "./test.mp4";
    char buffer[BUFFER_SIZE] ={'\0'};
    int flag = 0; int nAddrLen = sizeof(si);
    int count = 0;
    int i = 0;

    struct ip_mreq_source mreqsrc;
    // 允许其他进程使用绑定的地址
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(bReuse));

    // 绑定到6666 端口

    si.sin_family = AF_INET;
    si.sin_port = htons(6666);
    si.sin_addr.s_addr = INADDR_ANY;
    bind(sock, (struct sockaddr*)&si, sizeof(si));

    // 加入多播组
    mcast.imr_interface.s_addr = INADDR_ANY;
    mcast.imr_multiaddr.s_addr = inet_addr("172.17.191.255"); // 多播地址为234.5.6.7
    setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast));


    // 设置带源的多播地址
    // 设置ip_mreq_source 结构

    mreqsrc.imr_interface.s_addr = inet_addr("172.17.165.102");
    mreqsrc.imr_multiaddr.s_addr = inet_addr("234.5.6.7");

    // 添加源地址172.17.186.150
    mreqsrc.imr_sourceaddr.s_addr = inet_addr("172.17.186.150");
    setsockopt(sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *)&mreqsrc, sizeof(mreqsrc));
    // 添加源地址172.17.187.3
    mreqsrc.imr_sourceaddr.s_addr = inet_addr("172.17.187.3");
    setsockopt(sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *)&mreqsrc, sizeof(mreqsrc));
    // 添加源地址172.17.187.3
    mreqsrc.imr_sourceaddr.s_addr = inet_addr("172.17.186.216");
    setsockopt(sock, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char *)&mreqsrc, sizeof(mreqsrc));

    // 接收多播组数据
    printf(" 开始接收多播组234.5.6.7 上的数据... \n");
    // 文件数据准备
    pFile = fopen(pFilePath,"wb+");
    if (NULL == pFile)
    {
    printf("文件打开失败");

    }

    while(1)


    int nRet = recvfrom(sock, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&si, &nAddrLen);
    if(nRet != -1)

        //cout<<buffer<<endl;
    fwrite(buffer,1,BUFFER_SIZE,pFile);
    printf("客户端接收 %d KB\n",++i);
    bzero(buffer,BUFFER_SIZE);
    }
    else

    break;
    }
    }
    fclose(pFile);
    close(sock);
    return 0;
    }
      

  4.   

    IGMP问题解决:
    更换了内核,就OK了。to:naruto12345
    我现在还没有进入接收组播的环节,被别的事给耽误了。
    丢包严重的话,可以抓抓包试试,看看在哪儿丢的,然后再解决。