问题背景:
业务在WM平台上开发,客户端与服务器之间传输采用HTTP协议,采用Wininet库进行的封装,由于业务的需要,在某些场合下需要采用wap接入点,在某些情况下,需要采用net接入点接入。
问题出现的情况:
GPRS拨号采用系统自带的ConnectionManager进行管理,调用的是ConnMgrEstablishConnectionSync函数进行同步拨号操作,在网络接入点进行切换时,需要调用ConnMgrEstablishConnectionSync函数重新拨号,每次切换时,拨号都能成功,但是网络接入点切换重新拨号成功后,首次HTTP请求高概率出现超时现象,超时时间从几秒到3分钟左右,用户体验极差。
分析过程:
1.最初怀疑接入点切换时,前一个接入点没有完全关闭,仔细分析了ConnMgrReleaseConnection函数, 确认有可能,这个函数只是通知系统关闭连接,改为RAS相关函数(这 是系统底层拨号函数,没有延迟)。调用RasHangUp函数确 认关闭连接。
2. 采用上述方案后,问题依旧,说明不是旧的接入点未完全 关闭问题。增加了新的检查函数,检查新的接入点连接状态,确认新的接入点完全正 常情况下,超时问题依旧存在。排除了接入点方面的问题。
3.分析UCWeb切换网络,很正常,通过手机上抓包,发现没有直接的HTTP协议包,只有TCP包,通过对TCP包 进行分析,里面传输的内容其实也是HTTP协 议的内容。推测是其采用socket来模拟的HTTP协议栈。
根据UCWeb的 情况,在我们的客户端添加了socket测试代码。 测试时机和上面相同。在网络接入点切换时。经过测试,发现网络切换时,无论哪种情况,都能连接成功。说明socket在网络切换时没有任何问题。
4. 进一步测试,每次网络切 换时,先通过socket对网络进 行测试,确保成功之后,然后再进行HTTP测 试,发现即使socket发送接收数据成功,HTTP问 题依旧,大概可以推断出Wininet库确实 有一些BUG,在处理这种网 络接入更新状况时,有其重 要缺陷。
问题解决办法:可能是断网或者切换网络后wininet库还在使用断网前的socket资 源引起,所以我们的解决方法就是在外围替wininet去做这些释放资源的事情。在切换网络后主动去释放socket资源,释放的方法就是调用WSACleanup(),问 题的关键是调用一次WSACleanup()还不行,因为WINSOCKET库 可能做了一些与COM组件类似的引用计数机制,我们需要不停的调用WSACleanup()直到这个函数返回WSANOTINITIALISED这个值为止。按程序逻辑来讲WSACleanup与WSAStartup一一对应,而实际测试中发现一般都是至少调用了2到3次WSACleanup()后 才返回WSANOTINITIALISED值,所以我们可以猜测一个应用程序或者DLL在使用wininet库的时候wininet库都会调用一次WSAStartup,从 而导致WINCSOCKET库的引用计数加1,而我们开发的应用中在多处使用了wininet库,所以要把socket资源清除干净则至少需要调用2-3次WSACleanup()才 行,清空完后我们就可以重新调用WSAStartup进行WINSOCKET库初始化了。
转载:http://blog.csdn.net/xingtian713/article/details/5498223