• 多媒体开发之--- Live555 server 获取不到本地ip 全为0


    今天把wis-streamer live555 移植到8148上面跑起来了,运行testOnDemandRTSPServer的时候发现,本地IP地址居然为0.0.0.0;

    于是乎就跟踪调试了下,看看它是如何获取本地IP地址的,觉得这个方法还行就记录下来。

    live555在不知道本地IP地址与网络接口的情况下,通过一个在本地某端口建立一个UDP连接,然后把这个UDP连接加入

    到一个组播组 ,当然要对这个组播组进行相应的设置,比如TTL,回环等等;

    然后通过UDP连接发送一个数据;

    最后通过这个UDP连接接收这个数据,并且解析相应的发送地址;

    大概流程就是这样了。

    具体的代码片段live555:groupsock/GroupsockHelper.cpp里:

    static Boolean badAddress(netAddressBits addr) {
    // Check for some possible erroneous addresses:
    netAddressBits hAddr = ntohl(addr);
    return (hAddr == 0x7F000001 /* 127.0.0.1 */
    || hAddr == 0
    || hAddr == (netAddressBits)(~0));
    }

    Boolean loopbackWorks = 1;

    netAddressBits ourIPAddress(UsageEnvironment& env) {
    static netAddressBits ourAddress = 0;
    int sock = -1;
    struct in_addr testAddr;

    if (ourAddress == 0) {
    // We need to find our source address
    struct sockaddr_in fromAddr;
    fromAddr.sin_addr.s_addr = 0;

    // Get our address by sending a (0-TTL) multicast packet,
    // receiving it, and looking at the source address used.
    // (This is kinda bogus, but it provides the best guarantee
    // that other nodes will think our address is the same as we do.)
    do {
    loopbackWorks = 0; // until we learn otherwise

    testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
    Port testPort(15947); // ditto

    sock = setupDatagramSocket(env, testPort);
    if (sock < 0) break;

    if (!socketJoinGroup(env, sock, testAddr.s_addr)) break;

    unsigned char testString[] = "hostIdTest";
    unsigned testStringLength = sizeof testString;

    if (!writeSocket(env, sock, testAddr, testPort, 0,
    testString, testStringLength)) break;

    // Block until the socket is readable (with a 5-second timeout):
    fd_set rd_set;
    FD_ZERO(&rd_set);
    FD_SET((unsigned)sock, &rd_set);
    const unsigned numFds = sock+1;
    struct timeval timeout;
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    int result = select(numFds, &rd_set, NULL, NULL, &timeout);
    if (result <= 0) break;

    unsigned char readBuffer[20];
    int bytesRead = readSocket(env, sock,
    readBuffer, sizeof readBuffer,
    fromAddr);
    if (bytesRead != (int)testStringLength
    || strncmp((char*)readBuffer, (char*)testString, testStringLength) != 0) {
    break;
    }

    loopbackWorks = 1;
    } while (0);

    if (!loopbackWorks) do {
    // We couldn't find our address using multicast loopback
    // so try instead to look it up directly.
    char hostname[100];
    hostname[0] = '/0';
    gethostname(hostname, sizeof hostname);
    if (hostname[0] == '/0') {
    env.setResultErrMsg("initial gethostname() failed");
    break;
    }

    #if defined(VXWORKS)
    #include <hostLib.h>
    if (ERROR == (ourAddress = hostGetByName( hostname ))) break;
    #else
    struct hostent* hstent
    = (struct hostent*)gethostbyname(hostname);
    if (hstent == NULL || hstent->h_length != 4) {
    env.setResultErrMsg("initial gethostbyname() failed");
    break;
    }
    // Take the first address that's not bad
    // (This code, like many others, won't handle IPv6)
    netAddressBits addr = 0;
    for (unsigned i = 0; ; ++i) {
    char* addrPtr = hstent->h_addr_list[i];
    if (addrPtr == NULL) break;

    netAddressBits a = *(netAddressBits*)addrPtr;
    if (!badAddress(a)) {
    addr = a;
    break;
    }
    }
    if (addr != 0) {
    fromAddr.sin_addr.s_addr = addr;
    } else {
    env.setResultMsg("no address");
    break;
    }
    } while (0);

    // Make sure we have a good address:
    netAddressBits from = fromAddr.sin_addr.s_addr;
    if (badAddress(from)) {
    char tmp[100];
    sprintf(tmp,
    "This computer has an invalid IP address: 0x%x",
    (netAddressBits)(ntohl(from)));
    env.setResultMsg(tmp);
    from = 0;
    }

    ourAddress = from;
    #endif

    if (sock >= 0) {
    socketLeaveGroup(env, sock, testAddr.s_addr);
    closeSocket(sock);
    }

    // Use our newly-discovered IP address, and the current time,
    // to initialize the random number generator's seed:
    struct timeval timeNow;
    gettimeofday(&timeNow, NULL);
    unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
    our_srandom(seed);
    }
    return ourAddress;
    }

    很有幸,我又搜索到了海狗哥的一片博客,他把这个功能剥离出来了,并且附上了源代码。

    地址如下:http://jeremiah.blog.51cto.com/539865/275791

    在linux下不能获取到IP地址的解决方法,设置一个默认网关即可:

    route add default gw xxx.xxx.xxx.xxx eth0

    原来是没设置默认网关,加上上面这条命令后就可以了

    http://blog.csdn.net/wesleyluo/article/details/6204635

    http://blog.sina.com.cn/s/blog_a4953eea01012jxv.html 368移植

    http://blog.csdn.net/ghostyu/article/details/7485537

    http://www.live555.com/wis-streamer/ 官网wis-streamer

  • 相关阅读:
    蓝桥杯训练 2n皇后问题
    AtCoder Grand Contest #026 B
    AtCoder Grand Contest #026 A
    AtCoder Beginner Contest 103
    7-26 单词长度(15 分)
    uva 10006 Carmichael Numbers
    java并发带返回结果的批量任务执行(CompletionService:Executor + BlockingQueue)
    并发容器之CopyOnWriteArrayList
    模板模式
    静态工具类中使用注解注入service
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/4119543.html
Copyright © 2020-2023  润新知