这几天在写http断点下传的实现,遇到问题:
* 开多个httpConnect, 每个Connect对应一个httpRequest, 如果超过4个httpConnect, sendHttpRequest时,阻塞住了.
只有前面的httpConnect任务完成后,被阻塞线程的sendHttpRequest才返回.
* 如果是下载不同服务器的文件, 则不会出现sendHttpRequest阻塞.
同事在stackoverflow上找到资料, 可以设置连接同一个服务器httpConnect的连接数为指定值,解决了这个问题。
2、WININET 的 超时据说是bug,那么同步应用只是try catch了,一般超时会在2-3分钟返回;
3、长连接,据说是wininet被限制在同时保持2个会话连接,多了就阻塞。可以尝试以下设置
inetSession.SetOption(INTERNET_OPTION_MAX_CONNS_PER_SERVER,&uParam,sizeof(int));
INTERNET_OPTION_CONNECT_TIMEOUT发送数据时间
INTERNET_OPTION_SEND_TIMEOUT、接受数据的时间
INTERNET_OPTION_RECEIVE_TIMEOUT、
INTERNET_OPTION_MAX_CONNS_PER_SERVER 服务器连接个数
INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER 服务器连接个数
整理一下。

HINTERNET FCHttpRequest::create_connect()
{
std::wstring strTemp = L"";
HINTERNET hConnect = NULL;
INTERNET_PORT nPort = INTERNET_DEFAULT_HTTP_PORT;
CLsStopWatchTick watch;
if (m_tmp_scheme == INTERNET_SCHEME_HTTPS)
{
nPort = INTERNET_DEFAULT_HTTPS_PORT;
}
watch.start();
hConnect = InternetConnect(m_http_session.GetHandle(), m_tmp_host.c_str(), nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
strTemp = ns_base::StringFormatV(
L"create_connect() : [FCHttpRequest = 0x%p][TID = %d] : hConnect = 0x%p\r\n",
this,
::GetCurrentThreadId(),
hConnect);
watch.StopAndShow(strTemp.c_str(), TRUE);
if (NULL != hConnect)
{
/// 试验过了, 在程序开始设置 HINTERNE 为NULL, 那种http连接数, 是没用的
/// 只有在InternetConnect 所在线程中, 对有效httpConnect设置指定连接数, 才有效
SetHttpMaxConnectNumberEx(hConnect);
}
return hConnect;
}


void FCHttpRequest::SetHttpMaxConnectNumberEx(HINTERNET hHandle)
{
BOOL bRc = FALSE;
DWORD dwErr = 0;
DWORD dwHttpConnectMax = 50/*5 * 5 * 2 + 10*/; ///< (5条任务,一个任务5条线程) * 2 + 10(备用数目)
DWORD dwRecvBufLen = 0;
BOOL bRcOld = FALSE;
DWORD dwHttpConnectOld = 0; ///< INTERNET_OPTION_MAX_CONNS_PER_SERVER's cnt
BOOL bRcOld10 = FALSE;
DWORD dwHttpConnectOld10 = 0; ///< INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER's cnt
dwHttpConnectOld = 0;
bRc = GetHttpMaxConnectNumberEx(hHandle, INTERNET_OPTION_MAX_CONNS_PER_SERVER, dwHttpConnectOld);
dwErr = ::GetLastError();
_ASSERT(bRc);
dwHttpConnectOld10 = 0;
bRc = GetHttpMaxConnectNumberEx(hHandle, INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER, dwHttpConnectOld10);
dwErr = ::GetLastError();
_ASSERT(bRc);
/// 设置不成功, 设置成功的,取出来还是原来的值.
bRc = InternetSetOption(hHandle,INTERNET_OPTION_MAX_CONNS_PER_SERVER,&dwHttpConnectMax,sizeof(DWORD));
dwErr = ::GetLastError();
// _ASSERT(bRc); ///< 虽然为FALSE, 但是已经有效果了
bRc = InternetSetOption(hHandle,INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER,&dwHttpConnectMax,sizeof(DWORD));
dwErr = ::GetLastError();
// _ASSERT(bRc); ///< 虽然为FALSE, 但是已经有效果了
/// 这里得到的连接数, 也是旧的, 但是从程序运行效果上看,已经生效了
dwHttpConnectOld = 0;
bRc = GetHttpMaxConnectNumberEx(hHandle, INTERNET_OPTION_MAX_CONNS_PER_SERVER, dwHttpConnectOld);
dwErr = ::GetLastError();
_ASSERT(bRc);
/// 这里得到的连接数, 也是旧的, 但是从程序运行效果上看,已经生效了
dwHttpConnectOld10 = 0;
bRc = GetHttpMaxConnectNumberEx(hHandle, INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER, dwHttpConnectOld10);
dwErr = ::GetLastError();
_ASSERT(bRc);
}


BOOL FCHttpRequest::GetHttpMaxConnectNumberEx(HINTERNET hHandle, DWORD dwOption, DWORD& dwCnt)
{
BOOL bRc = FALSE;
DWORD dwRecvBufLen = 0;
dwCnt = 0;
bRc = InternetQueryOption(
NULL,
dwOption,
NULL,
&dwRecvBufLen);
if (!bRc)
{
_ASSERT(dwRecvBufLen == sizeof(DWORD));
bRc = ::InternetQueryOption(
NULL,
dwOption,
(LPVOID)&dwCnt,
&dwRecvBufLen);
_ASSERT(bRc);
}
return bRc;
}

博客讨论了在Windows下使用WinINet库进行HTTP请求时遇到的问题,包括当打开的HTTP连接超过4个导致阻塞以及超时问题。作者提到,这可能是由于WinINet的限制,如最大连接数和超时设置。通过设置INTERNET_OPTION_MAX_CONNS_PER_SERVER和相关超时选项,可以调整连接数和超时行为,从而解决这些问题。提供的代码示例展示了如何设置HTTP连接的最大数量。
1424

被折叠的 条评论
为什么被折叠?



