MFC如何利用CInternetSession、CHttpConnection和CHttpFile下载动态网页中的链接 MFC CHttpConnection 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 第一个参数是URL地址,第二个参数是本地保存地址INT Dialog1::GetFile(const CString strUrl,const CString strSavePath) { //检查传入的两个参数 if (strUrl.IsEmpty()) return -5; if (strSavePath.IsEmpty()) return -6; unsigned short nPort; //用于保存目标HTTP服务端口 CString strServer, strObject; //strServer用于保存服务器地址,strObject用于保存文件对象名称 DWORD dwServiceType,dwRet; //dwServiceType用于保存服务类型,dwRet用于保存提交GET请求返回的状态号 //解析URL,获取信息 if(!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort)) { //解析失败,该Url不正确 return -1; } //创建网络连接对象,HTTP连接对象指针和用于该连接的HttpFile文件对象指针,注意delete CInternetSession intsess; CHttpFile *pHtFile = NULL; //建立网络连接 CHttpConnection *pHtCon = intsess.GetHttpConnection(strServer,nPort); if(pHtCon == NULL) { //建立网络连接失败 intsess.Close(); return -2; } //发起GET请求 pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject); if(pHtFile == NULL) { //发起GET请求失败 intsess.Close(); delete pHtCon;pHtCon = NULL; return -3; } //提交请求 pHtFile->SendRequest(); //获取服务器返回的状态号 pHtFile->QueryInfoStatusCode(dwRet); if (dwRet != HTTP_STATUS_OK) { //服务器不接受请求 intsess.Close(); delete pHtCon;pHtCon = NULL; delete pHtFile;pHtFile = NULL; return -4; } //获取文件大小 UINT nFileLen = (UINT)pHtFile->GetLength(); DWORD dwRead = 1; //用于标识读了多少,为1是为了进入循环 //创建缓冲区 CHAR *szBuffer = new CHAR[nFileLen+1]; TRY { //创建文件 CFile PicFile(strSavePath,CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive); while(dwRead>0) { //清空缓冲区 memset(szBuffer,0,(size_t)(nFileLen+1)); //读取到缓冲区 dwRead = pHtFile->Read(szBuffer,nFileLen); //写入到文件 PicFile.Write(szBuffer,dwRead); } //关闭文件 PicFile.Close(); //释放内存 delete []szBuffer; delete pHtFile; delete pHtCon; //关闭网络连接 intsess.Close(); } CATCH(CFileException,e) { //释放内存 delete []szBuffer; delete pHtFile; delete pHtCon; //关闭网络连接 intsess.Close(); return -7; //读写文件异常 } END_CATCH return 0; } 先POST 账号密码进行登录。再下载文件。具体账号密码要以什么格式POST,抓HTTP包分析就知道了。以你说的这个网站为例,我手工登录一下,抓到的包是:一看就很明白了action=login&login_username=admin&login_password=5201314是POST提交的数据包内容,login_username=你的账号。login_password=你的密码。POST的目标地址是http://202.158.161.59/graph_xport.php 进行了些修改,可是最后得到的数据成乱码了,不知道是哪里出了问题INT Dialog1::GetFile(const CString strUrl,const CString strSavePath) { unsigned short nPort; //用于保存目标HTTP服务端口 CString strServer, strObject; //strServer用于保存服务器地址,strObject用于保存文件对象名称 DWORD dwServiceType,dwRet; //dwServiceType用于保存服务类型,dwRet用于保存提交GET请求返回的状态号 //解析URL,获取信息 if(!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort)) { //解析失败,该Url不正确 return -1; } //创建网络连接对象,HTTP连接对象指针和用于该连接的HttpFile文件对象指针,注意delete CInternetSession intsess; CHttpFile *pHtFile = NULL; //建立网络连接 CHttpConnection *pHtCon = intsess.GetHttpConnection(strServer,nPort,_T("ngb"),_T("ngb")); if(pHtCon == NULL) { //建立网络连接失败 intsess.Close(); return -2; } CString FormDataType = _T("Content-Type: application/x-www-form-urlencoded"); CString m_formdat = _T("action=login&login_username=ngb&login_password=ngb"); //发起GET请求 pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject); if(pHtFile == NULL) { //发起GET请求失败 intsess.Close(); delete pHtCon;pHtCon = NULL; return -3; } //提交请求 pHtFile->AddRequestHeaders(_T("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, */*")); pHtFile->AddRequestHeaders(_T("Referer: http://202.158.161.59/graph_xport.php?local_graph_id=286&rra_id=1&view_type=")); pHtFile->AddRequestHeaders(_T("Accept-Language: zh-cn")); pHtFile->AddRequestHeaders(_T("Content-Type: application/x-www-form-urlencoded")); pHtFile->AddRequestHeaders(_T("Accept-Encoding: gzip, deflate")); pHtFile->AddRequestHeaders(_T("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)")); pHtFile->AddRequestHeaders(_T("Connection: Keep-Alive")); pHtFile->AddRequestHeaders(_T("Cache-Control: no-cache")); pHtFile->AddRequestHeaders(_T("Cookie: Cookie: Cacti=6j0650vpqb4vomm2oothp7m272;")); pHtFile->SendRequest(FormDataType,(LPVOID)(LPCTSTR)m_formdat,m_formdat.GetLength()); //获取服务器返回的状态号 pHtFile->QueryInfoStatusCode(dwRet); if (dwRet != HTTP_STATUS_OK) { //服务器不接受请求 intsess.Close(); delete pHtCon;pHtCon = NULL; delete pHtFile;pHtFile = NULL; return -4; } //获取文件大小 UINT nFileLen = (UINT)pHtFile->GetLength(); DWORD dwRead = 1; //用于标识读了多少,为1是为了进入循环 //创建缓冲区 CHAR *szBuffer = new CHAR[nFileLen+1]; TRY { //创建文件 CFile PicFile(strSavePath,CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive); while(dwRead>0) { //清空缓冲区 memset(szBuffer,0,(size_t)(nFileLen+1)); //读取到缓冲区 dwRead = pHtFile->Read(szBuffer,nFileLen); //写入到文件 PicFile.Write(szBuffer,dwRead); } //关闭文件 PicFile.Close(); //释放内存 delete []szBuffer; delete pHtFile; delete pHtCon; //关闭网络连接 intsess.Close(); } CATCH(CFileException,e) { //释放内存 delete []szBuffer; delete pHtFile; delete pHtCon; //关闭网络连接 intsess.Close(); return -7; //读写文件异常 } END_CATCH return 0; } 通过抓包比对大致了解了一下,发现我发送过去的数据出问题了,CString转换LPvoid的时候为何会多出许多“.”呢?原始数据是CString = _T("action=login&login_username=ngb&login_password=ngb");下面两张图分别是IE的抓包和MFC的抓包 pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject); 这里,你应该发起POST请求,而不是GET请求 问下一个小小的问题 问关于LoadLibrary失败的问题,详见内容 网络传输中如何保证数据的同步? 熟练函数与类 MFC工程中用tinyXml的实例程序 可以发我一份吗 关于centerwindow()与cs.style设置之间的问题 要找工作了,请大家给点意见 求直线或曲线控件。 求助:如何用MFC做一张简单地图? 我是新手加超级菜鸟,有高手能帮帮忙吗? MFC 多文档工程怎么转换成BCG的工程 MFC中,单文档的程序,有一个主对话框,和子对话框,现在想要主对话框获得子对话框的变量值,怎么实现?
INT Dialog1::GetFile(const CString strUrl,const CString strSavePath)
{
//检查传入的两个参数
if (strUrl.IsEmpty())
return -5;
if (strSavePath.IsEmpty())
return -6;
unsigned short nPort; //用于保存目标HTTP服务端口
CString strServer, strObject; //strServer用于保存服务器地址,strObject用于保存文件对象名称
DWORD dwServiceType,dwRet; //dwServiceType用于保存服务类型,dwRet用于保存提交GET请求返回的状态号
//解析URL,获取信息
if(!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort))
{
//解析失败,该Url不正确
return -1;
}
//创建网络连接对象,HTTP连接对象指针和用于该连接的HttpFile文件对象指针,注意delete
CInternetSession intsess;
CHttpFile *pHtFile = NULL; //建立网络连接
CHttpConnection *pHtCon = intsess.GetHttpConnection(strServer,nPort);
if(pHtCon == NULL)
{
//建立网络连接失败
intsess.Close();
return -2;
}
//发起GET请求 pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject);
if(pHtFile == NULL)
{
//发起GET请求失败
intsess.Close();
delete pHtCon;pHtCon = NULL;
return -3;
}
//提交请求
pHtFile->SendRequest();
//获取服务器返回的状态号
pHtFile->QueryInfoStatusCode(dwRet);
if (dwRet != HTTP_STATUS_OK)
{
//服务器不接受请求
intsess.Close();
delete pHtCon;pHtCon = NULL;
delete pHtFile;pHtFile = NULL;
return -4;
}
//获取文件大小
UINT nFileLen = (UINT)pHtFile->GetLength();
DWORD dwRead = 1; //用于标识读了多少,为1是为了进入循环
//创建缓冲区
CHAR *szBuffer = new CHAR[nFileLen+1];
TRY
{
//创建文件
CFile PicFile(strSavePath,CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive);
while(dwRead>0)
{
//清空缓冲区
memset(szBuffer,0,(size_t)(nFileLen+1));
//读取到缓冲区
dwRead = pHtFile->Read(szBuffer,nFileLen);
//写入到文件
PicFile.Write(szBuffer,dwRead);
}
//关闭文件
PicFile.Close();
//释放内存
delete []szBuffer;
delete pHtFile;
delete pHtCon;
//关闭网络连接
intsess.Close();
}
CATCH(CFileException,e)
{
//释放内存
delete []szBuffer;
delete pHtFile;
delete pHtCon;
//关闭网络连接
intsess.Close();
return -7; //读写文件异常
}
END_CATCH
return 0;
}
具体账号密码要以什么格式POST,抓HTTP包分析就知道了。
以你说的这个网站为例,我手工登录一下,抓到的包是:一看就很明白了
action=login&login_username=admin&login_password=5201314
是POST提交的数据包内容,login_username=你的账号。login_password=你的密码。
POST的目标地址是http://202.158.161.59/graph_xport.php
INT Dialog1::GetFile(const CString strUrl,const CString strSavePath)
{
unsigned short nPort; //用于保存目标HTTP服务端口
CString strServer, strObject; //strServer用于保存服务器地址,strObject用于保存文件对象名称
DWORD dwServiceType,dwRet; //dwServiceType用于保存服务类型,dwRet用于保存提交GET请求返回的状态号
//解析URL,获取信息
if(!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort))
{
//解析失败,该Url不正确
return -1;
}
//创建网络连接对象,HTTP连接对象指针和用于该连接的HttpFile文件对象指针,注意delete
CInternetSession intsess;
CHttpFile *pHtFile = NULL; //建立网络连接
CHttpConnection *pHtCon = intsess.GetHttpConnection(strServer,nPort,_T("ngb"),_T("ngb"));
if(pHtCon == NULL)
{
//建立网络连接失败
intsess.Close();
return -2;
}
CString FormDataType = _T("Content-Type: application/x-www-form-urlencoded");
CString m_formdat = _T("action=login&login_username=ngb&login_password=ngb");
//发起GET请求
pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject);
if(pHtFile == NULL)
{
//发起GET请求失败
intsess.Close();
delete pHtCon;pHtCon = NULL;
return -3;
}
//提交请求
pHtFile->AddRequestHeaders(_T("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, */*"));
pHtFile->AddRequestHeaders(_T("Referer: http://202.158.161.59/graph_xport.php?local_graph_id=286&rra_id=1&view_type="));
pHtFile->AddRequestHeaders(_T("Accept-Language: zh-cn"));
pHtFile->AddRequestHeaders(_T("Content-Type: application/x-www-form-urlencoded"));
pHtFile->AddRequestHeaders(_T("Accept-Encoding: gzip, deflate"));
pHtFile->AddRequestHeaders(_T("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)"));
pHtFile->AddRequestHeaders(_T("Connection: Keep-Alive"));
pHtFile->AddRequestHeaders(_T("Cache-Control: no-cache"));
pHtFile->AddRequestHeaders(_T("Cookie: Cookie: Cacti=6j0650vpqb4vomm2oothp7m272;"));
pHtFile->SendRequest(FormDataType,(LPVOID)(LPCTSTR)m_formdat,m_formdat.GetLength()); //获取服务器返回的状态号
pHtFile->QueryInfoStatusCode(dwRet);
if (dwRet != HTTP_STATUS_OK)
{
//服务器不接受请求
intsess.Close();
delete pHtCon;pHtCon = NULL;
delete pHtFile;pHtFile = NULL;
return -4;
}
//获取文件大小
UINT nFileLen = (UINT)pHtFile->GetLength();
DWORD dwRead = 1; //用于标识读了多少,为1是为了进入循环
//创建缓冲区
CHAR *szBuffer = new CHAR[nFileLen+1];
TRY
{
//创建文件
CFile PicFile(strSavePath,CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive);
while(dwRead>0)
{
//清空缓冲区
memset(szBuffer,0,(size_t)(nFileLen+1));
//读取到缓冲区
dwRead = pHtFile->Read(szBuffer,nFileLen);
//写入到文件
PicFile.Write(szBuffer,dwRead);
}
//关闭文件
PicFile.Close();
//释放内存
delete []szBuffer;
delete pHtFile;
delete pHtCon;
//关闭网络连接
intsess.Close();
}
CATCH(CFileException,e)
{
//释放内存
delete []szBuffer;
delete pHtFile;
delete pHtCon;
//关闭网络连接
intsess.Close();
return -7; //读写文件异常
}
END_CATCH
return 0;
}
原始数据是CString = _T("action=login&login_username=ngb&login_password=ngb");
下面两张图分别是IE的抓包和MFC的抓包