live555学习心得二(获取本地IP地址方法1)

今天在linux下编译了下live555程序,运行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 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

你可能感兴趣的:(C,/C++编程学习)