[http] WinInet发送或接收函数超时的bug & 解决办法

来源:互联网 发布:双十一网络销售情况 编辑:程序博客网 时间:2024/05/03 09:32

项目中有http的IO操作 使用了WinInet进行网络数据的发送和接收 

但是使用中发现 WinInet的读写函数(HttpSendRequest和InternetReadFile)经常会卡住 函数很久才会返回 有时甚至不返回


众所周知 使用socket进行网络IO操作时 可以按照如下方法设置网络超时的时长:

bool SetTimeoutValue(SOCKET& socket, int timeout){// 设置发送函数超时的时长if (setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)return false;// 设置接收函数超时的时长if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)return false;return true;}


WinInet是否也有类似的函数?经过搜索 发现WinInet的确也有类似的函数InternetSetOption  + INTERNET_OPTION_CONNECT_TIMEOUT

但是根据微软官方回复 获知该API有bug 如果非要实现超时逻辑 需要采用多线程的方式实现 现将多线程方法的伪代码贴出来:

unsigned __stdcall SendRecvThread(void* pParam){// TODO :调用WinInet进行发送和接收,返回执行结果}void CHttpWininet::ReleaseWininet(){// TODO :释放相关的HINTERNET对象 }bool CHttpWininet::RequestNetIO(DWORD dwTimeout){     bool bResult = false;HANDLE hThreadHandle = (HANDLE)_beginthreadex(0, 0, SendRecvThread, this, 0, 0);if (!hThreadHandle || (hThreadHandle == INVALID_HANDLE_VALUE))return bResult;if (WaitForSingleObject(hThreadHandle, dwTimeout) == WAIT_TIMEOUT){ReleaseWininet(); // 多线程中的网络IO超时了 释放HINTERNET对象   WaitForSingleObject(hThreadHandle, INFINITE); // 释放HINTERNET后阻塞的IO函数就会返回。等待线程结束}else{DWORD dwExitFlag = 0;::GetExitCodeThread(hThreadHandle, &dwExitFlag);bResult = dwExitFlag ? true : false; // 多线程退出码标识了执行结果}CloseHandle(hThreadHandle);   ReleaseWininet(); return bResult;}
1 0
原创粉丝点击