在Libjingle+Linphone for Windows的voice call测试中, 遇到了一些问题. 而这些问题的root cause竟然源于Google code的一些小bug. 这里先指出一个. SocketAddress这个类的其中一个构造函数是:
这个构造函数的参数看起来很简单, 一般人很少注意上面那堆罗嗦的注释, 第一个参数是hostname, 第二参数是port. 问题就出在hostname上面. 那这个构造函数的实现是什么呢?
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()函数试图将一个本地机器不合法的
(mysuperbaby)地址绑扎到套接字时产生。它也可能在connect()、sendto()、WSAConnect()、WSAJoinLeaf() 或WSASendTo()函数调用时因远程机器的远程地址或端口号非法(如0地址或0端口号)而 产生。 |