多媒体开发之--- 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