首页 > 网络新闻 > 站长博客 > 正文

分析QQ是如何检查网络状况并自动重新登录上线的

时间:2011-11-07 08:22 作者:QQ地带 我要评论

本人发现一些IM在网络异常后,如何决定自动重新上线这个问题上,QQ做得不错。
 
比如我将本地连接给禁用了或者发现异常后。我觉得对于UDP这种通信模式的应用软件是不容易立刻检测到网络异常的。但是就我测试发现QQ有这样的检测机能。他会检测到网络是不可用的,所以不会盲目的自动不断尝试重新登录(小企鹅一直灰色)。而当我重新启用本地连接后,QQ几乎立刻就检测到网络可用。自动重新登录(小企鹅挥动起来了)。
作为一个要保持在线的桌面应用软件,这个检测机制确实很有意义。
 
问题:QQ是如何快速得到本地网络可用的呢?
思路:是否windows有这样的事件通知接口?
 
先OD挂上QQ, 验证这个思路我首先想到QQ检测到网络不可用后立刻托盘图标变灰色。于是下断点Shell_NotifyIconW,然后手动禁用本地连接。断点立刻触发。开始检测栈回溯的相关代码。 
 
 
 
回溯返回后看到的显然不是我想要的:通过这3个API断定是QQ自己实现的一个消息队列机制。一个线程一直到执行WaitForSingleObject等待事件。事件等待其他线程插入队列消息后处理之。 查看hEvent的值后继而需要“条件断点”SetEvent了。重复启用本地连接再禁用本地连接,这样可以断下想要的那个关键线程。断下SetEvent后查看耐心的翻阅回溯栈的相关代码,我也是走马观花的看,突然某代码段一个字符串“OnConnectionBroken”出现让我喜出望外啊,QQ内部有很多方便Log而加上去的字符串信息对我这种肤浅的分析人是很有意义的。
 
 
 
 
继而在附近发现QQ的Common.dll有个导出函数,函数名是IsNetConnectionOK,显然核心代码是他了。剩下的精力就应该是深入IsNetConnectionOK。
 
 
 
IsNetConnectionOK这个函数根据断点发生频率是有一个Timer大概每3秒会触发一次。但是我在win7下测试的实际情况,禁用网络连接后发现几乎一直不需要有2或3秒的延时。
 
针对是否windows有类似OnConnectionBroken这样的事件通知接口,如果有那么QQ也不用搞个timer不停的执行IsNetConnectionOK。
 
IsNetConnectionOK 内部有一处代码调用了CoCreateInstance,根据参数的CLSID搜索出来的系统组件叫CLSID_NetworkListManager,这个MSDN上介绍只有vista+的系统才有。我自己也折腾了一下这个接口写了点测试代码,后来发现MSDN有C++和C#的sample。
MSDN sample:
C#:  http://ppe.archive.msdn.microsoft.com/NLM/Release/ProjectReleases.aspx?ReleaseId=3010
C++: http://ppe.archive.msdn.microsoft.com/NLM/Release/ProjectReleases.aspx?ReleaseId=3011
 
Vista+的环境可以用CLSID_NetworkListManager组件接口事件通知快速检测系统网络是否可用。
至于XP环境如何快速检测本地网络是否可用,timer是必须的了,具体还得深入了解IsNetConnectionOK。里面的代码量也不少。由于我目前时间有限打算日后再深入研究。
 
此贴也就是抛砖引玉,如果你知道细节的话就麻烦抛出玉来吧。省下菜鸟们的一点时间和精力。 如果各位看官不过瘾急着要了解XP环境的检测手段,就先自己操刀分析IsNetConnectionOK。

顶一下
(1)
100%
踩一下
(0)
0%

Google提供的广告