在Libjingle+Linphone for Windows的voice call测试中, 遇到了一些问题. 而这些问题的root cause竟然源于Google code的一些小bug. 这里先指出一个.
SocketAddress这个类的其中一个构造函数是:
// Creates the address with the given host and port. If use_dns is true,
// the hostname will be immediately resolved to an IP (which may block for
// several seconds if DNS is not available). Alternately, set use_dns to
// false, and then call Resolve() to complete resolution later, or use
// SetResolvedIP to set the IP explictly.
SocketAddress(const std::string& hostname, int port);
这个构造函数的参数看起来很简单, 一般人很少注意上面那堆罗嗦的注释, 第一个参数是hostname, 第二参数是port. 问题就出在hostname上面.
那这个构造函数的实现是什么呢?
SocketAddress::SocketAddress(const std::string& hostname, int port) {
SetIP(hostname);
SetPort(port);
}
void SocketAddress::SetIP(const std::string& hostname) {
hostname_ = hostname;
ip_ = StringToIP(hostname);
}
uint32 SocketAddress::StringToIP(const std::string& hostname) {
uint32 ip = 0;
StringToIP(hostname, &ip);
return ip;
}
bool SocketAddress::StringToIP(const std::string& hostname, uint32* ip) {
in_addr addr;
if (inet_aton(hostname.c_str(), &addr) == 0)
return false;
*ip = NetworkToHost32(addr.s_addr);
return true;
}
#ifdef WIN32
// Win32 doesn't provide inet_aton, so we add our own version here.
// Since inet_addr returns 0xFFFFFFFF on error, if we get this value
// we need to test the input to see if the address really was 255.255.255.255.
// This is slightly fragile, but better than doing nothing.
int inet_aton(const char* cp, struct in_addr* inp) {
inp->s_addr = inet_addr(cp);
return (inp->s_addr == INADDR_NONE &&
strcmp(cp, "255.255.255.255") != 0) ? 0 : 1;
}
#endif // WIN32
hostname被传递的顺序是SocketAddress()->SetIP()->StringToIP()->inet_aton()->inet_addr()
那我们再来看看inet_addr()的说明, 这是一个系统函数. Refer to:
http://msdn.microsoft.com/en-us/library/ms738563%28v=vs.85%29.aspx
写道
The inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure.
Parameters
cp [in]
A NULL-terminated character string representing a number expressed in the Internet standard ".'' (dotted) notation.
也就是说inet_addr()函数的参数是一个IP地址字符串, 如"192.168.1.1".
而SocketAddress类的构造函数的参数按照字面意思应该是hostname (主机名), 所以如果传入hostname, 最终inet_addr()函数将无法正确解析, 那么构造的对象将会代表一个无效的地址.
偶被这个隐藏的小bug捉弄了好几天, 差点放弃Libjingle的测试, 幸亏最终静下心来仔细分析了一下. 如果传入hostname (比如"localhost") 构造这样一个SocketAddress对象, 然后调用SendTo()发送数据, 会返回-1, 系统错误码为WSAEADDRNOTAVAIL (10049) Cannot assign requested address.
写道
被请求的地址在它的环境中是不合法的。通常地在bind()函数试图将一个本地机器不合法的
地址绑扎到套接字时产生。它也可能在connect()、sendto()、WSAConnect()、WSAJoinLeaf()
或WSASendTo()函数调用时因远程机器的远程地址或端口号非法(如0地址或0端口号)而
产生。
分享到:
相关推荐
Libjingle是Google提供的C++组件集,它为Google Talk的点对点通讯与语音呼叫功能提供交互操作性。组件包包括了Jingle和Jingle-Audio的google实现的源代码,它们是XMPP标准的推荐扩展,目前试验版可用。 我们发布此...
libjingle-0.5.1.zip,WebRTC nat打洞专用。
VS2010编译libjingle0.6.2步骤 图文并茂
目前GOOGLECODE上的最新更新删除了libjingle.vcproj文件,采用scons脚本进行编译,增加了学习门槛,本次下载包增加了libjingle.vcproj文件并且已经通过了vs2005编译,方便大家学习使用。 Libjingle - Google Talk ...
libjingle0.6.14 版本,p2p学习
带GIPS的libjingle source
libjingle0.6.14编译好的.lib
作者:Group ArmTalk 文档:2011-11-30 ...1. Libjingle是什么 2. 怎么获取Libjingle 3. 怎么交叉编译Libjingle(arm-linux-) 以下是个人说明: 要在ARM架构的嵌入式设备使用libjingle,可以参考该文档进行操作
libjingle vs2010 编译通过
libjingle 0.6.6、0.6.9以及最新的0.6.10在windows和ubuntu-linux上编译通过,现将编译过程及遇到的一些问题总结分享一下
libjingle 中文 手册,很不错的哦,描述的很清楚,还有使用范例
android Webrtc ( libjingle_peerconnection_builds 包括例子
libjingle源码(含GIPS LITE),方便大家编译上传
从官网上复制的libjingle开发者指南和源码索引,你也可以访问一下网站: https://developers.google.com/talk/libjingle/developer_guide
libjingle_peerconnection.jar libjingle_peerconnection.so
gtalk的库,可以用做p2p通信软件和基础库.
libjingle的封装库,可以快速开发基于XMPP的客户端通信,方便试用
最完全,最全面的Android框架列表libjingle_peerconnection_so
源:https://developers.google.com/talk/libjingle/reference/ 语言:English 源于谷歌的libjingle的API。 个人整理成表格,方便开发时查找。 希望能帮助相关开发者。