InternetQueryDataAvailable 读取字节数为0的解决方法
来源:互联网 发布:淘宝搜白夜追凶接电话 编辑:程序博客网 时间:2024/05/17 15:04
从远程读取数据时, 一般是调用2个函数的组合 : InternetQueryDataAvailable + InternetReadFile
只有 InternetQueryDataAvailable 查到远端提供了数据, 才用InternetReadFile读取数据.
最近看见一个现象, 远端是有文件的, 有时也下载了一半, 但是再调用InternetQueryDataAvailable, 返回的可操作字节数总是为0
这时, InternetQueryDataAvailable是超时返回的, 不像平时那样, 返回的很快.
这时, 如果是直接调用InternetReadFile, 也只能超时返回.
如下:
if (!InternetQueryDataAvailable(m_http_request, &dwBytesAvailable, 0, 0)) { // 有可能是 (getLastError() == NO MORE FILES), 算错误么? // 下载时, 会出现这种错误码么? m_http_response.m_bfinal_read_result = FALSE; eRc = ns_e_http_request_status::err_read_remotefile; WriteLogEx(L"break 2 FCHttpRequest::proc_http_request()"); goto END_proc_http_request; } if (dwBytesAvailable <= 0) { m_http_response.m_bfinal_read_result = TRUE; eRc = ns_e_http_request_status::ok; ///< no more data WriteLogEx(L"InternetQueryDataAvailable (dwBytesAvailable <= 0)"); goto END_proc_http_request; }
...
bReadResult = InternetReadFile(m_http_request, pcBufRead, HTTP_READ_FILE_BUFFER_SIZE, &dwBytesReadBack); if (!bReadResult) { m_http_response.m_bfinal_read_result = FALSE; eRc = ns_e_http_request_status::err_read_remotefile; // WriteLogEx(L"break 4 FCHttpRequest::proc_http_request()"); goto END_proc_http_request; } if (0 == dwBytesReadBack) {
我猜想我用程序下载和第三方的下载功能有啥区别呢?
我突然想到了下载时用到的userAgent, 以前也想改改, 但是因为下载组件整理后, 没有亲自看到不能下载的原因,就没动手.
// Get user-agent used by IE. std::wstring GenDifferentUserAgent() { DWORD n = 1024; char t[1024] = {0}; std::string strSession = ""; std::wstring::size_type nPos = std::wstring::npos; std::wstring strTemp = L""; if (m_user_agent.size() <= 0) { ObtainUserAgentString(0, t, &n); strSession = t; //为了防止服务器停止响应某个固定的Agen, 有必须要使userAgent每次不同 // M$给出的userAgent样例 // Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1) // 本地实际得到的userAgent // Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E) strTemp = ns_base::A2Wex(strSession.c_str()); /// 找到第一个" (" nPos = strTemp.find(L" ("); if (std::wstring::npos != nPos) { strTemp = strTemp.substr(nPos, -1); } m_user_agent = ns_base::StringFormatV(L"Mozilla%I64x/4.0%s", (LONGLONG)time(NULL), strTemp.c_str()).c_str(); } return m_user_agent; }
HINTERNET FCHttpRequest::create_session_real(){ BOOL bRc = FALSE; DWORD dw_timeout = 30 * 1000; // override the 30 second timeout std::wstring strTemp = L""; std::wstring s = L""; HINTERNET hSession = NULL; if (m_http_request_header.m_proxy_ip.size() > 0) { s = ns_base::StringFormatV(_T("%s:%d"), m_http_request_header.m_proxy_ip.c_str(), m_http_request_header.m_proxy_port) ; hSession = InternetOpen( m_http_request_header.m_user_agent.c_str(), INTERNET_OPEN_TYPE_PROXY, s.c_str(), NULL, 0); } else { hSession = InternetOpen( m_http_request_header.m_user_agent.c_str(), INTERNET_OPEN_TYPE_DIRECT, // INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); } if (NULL != hSession) { // set proxy username and password if (m_http_request_header.m_proxy_username.size()) { InternetSetOption( hSession, INTERNET_OPTION_PROXY_USERNAME, (LPVOID)(LPCTSTR)m_http_request_header.m_proxy_username.c_str(), m_http_request_header.m_proxy_username.size()) ; } if (m_http_request_header.m_proxy_password.size()) { InternetSetOption( hSession, INTERNET_OPTION_PROXY_PASSWORD, (LPVOID)(LPCTSTR)m_http_request_header.m_proxy_password.c_str(), m_http_request_header.m_proxy_password.size()) ; } /// internetreadfile block for long long time, so set timeout to it bRc = InternetSetOption(hSession, INTERNET_OPTION_RECEIVE_TIMEOUT, &dw_timeout, sizeof(DWORD)); if (!bRc) { OutputDebugStringW(L""); } } return hSession;}
ns_e_http_request_status::e_http_request_status FCHttpRequest::DlFilePart(){ ns_e_http_request_status::e_http_request_status eRc = ns_e_http_request_status::unknown; m_start_tick = GetTickCount(); _ASSERT(NULL != m_pOwner); eRc = proc_create_session(); if (!IsValidHttpStatus(eRc)) { goto END_DlFilePart; } if (NULL == m_phttp_session) { eRc = ns_e_http_request_status::err_create_session; goto END_DlFilePart; } if (IsNeedQuit()) { eRc = ns_e_http_request_status::owner_cancel; goto END_DlFilePart; } eRc = proc_http_connect(); if (!IsValidHttpStatus(eRc))
改了userAgent后, 当服务器回答没有数据可提供时, 当作错误退出该下载子任务.
由下载失败再重试时, 由于userAgent重新变了一个, 就可以下载数据了.
如果不改userAgent, 即使失败重试, 还会遇到同样的 InternetQueryDataAvailable (dwBytesAvailable == 0)
如果不改userAgent, 通过实验, 发现服务器过一会(大约5~10分钟)才会重新响应 InternetQueryDataAvailable (dwBytesAvailable != 0)
感觉还是http服务器有啥BUG.
暂时先这么解决了, 看以后能不能知道 InternetQueryDataAvailable (dwBytesAvailable == 0)的真正原因.
- InternetQueryDataAvailable 读取字节数为0的解决方法
- scala读取HDFS文件,每次读取一定的字节数
- scala读取HDFS文件,每次读取一定的字节数
- 编写一个程序,它读取一个文件以判断其中的字节数,然后使用0覆盖所有的字节
- 得到字节数,英文为两个的,中文为一个
- Socket读取报文(字节流)不会退出循环的解决方法
- 按照字节数读取文件
- OpenCV 读取图片时候行字节数的算法
- 硬盘、U盘起死回生的方法:文件系统显示为RAW文件系统,总共字节为0,可用字节为0且无法读取 的解决办法
- 将一个4个字节的数拆分为4单个字节的数
- 将读取的图片的InputStream流转为字节流
- 将读取的图片的InputStream流转为字节流
- 输入为一个字符串和字节数,输出为按字节截取的字符串
- 输入为一个字符串和字节数,输出为按字节截取的字符串
- kinect使用cvCreateVideoWriter不成功,depth.avi和rgb.avi为0字节的解决方法
- 获取文件夹的大小(大小为字节数)
- 读取字节的方式
- C语言,进制转换(输入一个字节内的数(0~255),然后将该数的转换为二进制数,然后将高四位和低四位互换)
- js常见事件
- Java基础—网络编程
- JMockit 如何 mock 异常
- MAC下快速查看 资源库 文件
- sqlserver导出 数据字典的SQL语句
- InternetQueryDataAvailable 读取字节数为0的解决方法
- 人脸检测与识别
- linux常用操作命令
- 报错:Didn't find class "**Activity" on path: DexPathList[dexElements=[****]
- ssh不用密码登陆
- NodeJs安装教程
- 位移操作其中的多个位
- Tomcat启动时,报java.io.EOFException异常
- Access violation reading location 在把一个vector传给写文件或者写对象的函数时报错