多媒体开发之--- 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
多媒体开发之--- Live555 server 获取不到本地ip 全为0的更多相关文章
- 多媒体开发之--- live555 vs2010/vs2013下编译,使用,测试
Ⅰ live555简介 Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现了对多种音视频编 ...
- 多媒体开发之---live555 分析客户端
live555的客服端流程:建立任务计划对象--建立环境对象--处理用户输入的参数(RTSP地址)--创建RTSPClient实例--发出DESCRIBE--发出SETUP--发出PLAY--进入Lo ...
- 多媒体开发之---live555的多线程支持,原本只是单线程,单通道
1)我对Live555进行了一次封装,但是Live555 是单线程的,里面定义的全局变量太多,我封装好dll库后,在客户端调用,因为多个对话框中要使用码流,我就定义了多个对象从设备端接收码流,建立多个 ...
- 多媒体开发之---h264 server rtsp
(1)live555 (2)gstreamer http://code.openhub.net/search?s=rtsp%20server (3)srs (4)ffmpeg
- Lodop获取客户端主网卡ip地址是0.0.0.0
LODOP技术手册的GET_SYSTEM_INFO篇,LODOP可以用语句获取到客户端很多信息,NetworkAdapter.1.IPAddress是主网卡IP地址,通常情况下是没问题的,不过如果当前 ...
- java获取登陆用户的IP地址
/** * 通过HttpServletRequest返回IP地址 * @param request HttpServletRequest * @return ip String * @throws E ...
- Modbus库开发笔记之九:利用协议栈开发Modbus TCP Server应用
前面我们已经完成了Modbus协议栈的开发,但这不是我们的目的.我们开发它的目的当然是要使用它来解决我们的实际问题.接下来我们就使用刚开发的Modbus协议栈开发一个Modbus TCP Server ...
- 使用 C# 开发 Kubernetes 组件,获取集群资源信息
写什么呢 前段时间使用 C# 写了个项目,使用 Kubernetes API Server,获取信息以及监控 Kubernetes 资源,然后结合 Neting 做 API 网关. 体验地址 http ...
- SQL Server获取下一个编码字符串的实现方案分割和进位
我在前一种解决方案SQL Server获取下一个编码字符实现和后一种解决方案SQL Server获取下一个编码字符实现继续重构与增强两篇博文中均提供了一种解决编码的方案,考虑良久对比以上两种方 ...
随机推荐
- 【BJOI2014/bzoj4530】大融合
题意 有 $n$ 个点,初始没有连边,要求支持两个动态操作: 1. 加一条边(保证之前两点不连通) 2. 查询过一条边的简单路径数量(就是两边连通块的大小的乘积) $n,Q\le 100000$ 题解 ...
- java面试题之哨兵如何判断主服务器是否下线?
通过流言协议来接收关于主服务器是否下线的信息,并使用投票协议来决定是否执行自动故障迁移,以及选择哪个从服务器作为新的主服务器.
- 我要好offer之 链表大总结
单链表是一种递归结构,可以将单链表看作特殊的二叉树(我把它叫做一叉树) 单链表的定义: /** * Definition for singly-linked list. * struct ListNo ...
- 【CF1020B】Badge(模拟)
题意:给定n个人,每个人指向第a[i]个人,要求输出从每个人开始第一个被访问到两次的人的编号 n<=1e3 思路: #include<cstdio> #include<cstr ...
- IPC 通信接口函数的名字
IPC三种通信机制是指:信号量.共享内存.消息队列 ,管道和命名管道,socket套接字 信号量:通过操作系统中的PV操作来实现: 共享内存:申请一块内存,进程A往共享内存中写,其他的进程就 ...
- delphi 四舍五入Round函数【百帖整理】
在最近版本的Delphi Pascal 编译器中,Round 函数是以 CPU 的 FPU (浮点部件) 处理器为基础的.这种处理器采用了所谓的 "银行家舍入法",即对中间值 (如 ...
- XA事务与MySQL
XA事务就是两阶段提交的一种实现方式 XA规范主要定义了事务管理器TM,和资源管理器RM之间的接口 根据2PC的规范,将一次事务分割成两个阶段 1. prepare阶段 TM向所有RM发送prepar ...
- 专访Nick McKeown:网络领域的游戏颠覆者
如果要找到一个过去10年在网络领域最热的词汇,那么非SDN(软件定义网络)莫属.在过去的十年间无论是学术机构还是标准组织,无论是电信巨擘还是互联网大厂都成其拥趸. 然而几乎每一件SDN的重大事件都离不 ...
- ML | Naive Bayes
what's xxx In machine learning, naive Bayes classifiers are a family of simple probabilistic classif ...
- SYN攻击SYN Attack
SYN攻击SYN Attack SYN Attack是一种DOS攻击方式.它利用的是TCP协议的漏洞,攻击目标,使其不在响应网络请求.在TCP协议中,需要三次握手,才能建立TCP连接.在握手过程中 ...