问一个关于使用wininet.lib的问题

sh0cker 2004-08-10 01:18:38
我想写一个多线程下载的命令行程序。但是在使用wininet.lib提供的api函数时遇到了问题
源代码如下
#include "stdio.h"
#include "windows.h"
#include "wininet.h"

void usage();
LPTSTR GetFileName(LPCTSTR lpszFilePath);
void ShowError(LPCSTR lpszFuntionName);

int main(int argc,char *argv[])
{
HINTERNET hSession;
HINTERNET hConnect;
HINTERNET hRequest;
const CHAR *lpszAcceptTypes = "*/*" ;
CHAR szServername[256]="www.******.com";
CHAR szObjectname[100]="***.exe";
INTERNET_PORT wPort = 80;
LPTSTR lpszAgent = NULL;

lpszAgent = GetFileName(argv[0]);
hSession = InternetOpen(lpszAgent,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if (hSession == NULL)
{
ShowError("InternetOpen");
return -1;
}
hConnect = InternetConnect(hSession,szServername,wPort/*INTERNET_DEFAULT_HTTP_PORT*/,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
if (hConnect == NULL)
{
ShowError("InternetConnect");
return -2;
}
hRequest = HttpOpenRequest(hConnect,"GET",szObjectname,NULL,NULL,&lpszAcceptTypes,INTERNET_FLAG_RELOAD,0);
if (hRequest == NULL)
{
ShowError("HttpOpenRequest");
return -3;
}
//CHAR szHttpHeader[256] = "Host: ***********\r\n";
//BOOL bRetSend = HttpSendRequest(hRequest,szHttpHeader,strlen(szHttpHeader),NULL,0);
BOOL bRetSend = HttpSendRequest(hRequest,NULL,0,NULL,0);
if (bRetSend == FALSE)
{
ShowError("HttpSendRequest");
return -4;
}
DWORD dwIndex=0;
CHAR szBuffer[32] = {0};
DWORD dwBufferLen=32;

BOOL bRetQueryInfo = HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH,szBuffer,&dwBufferLen,&dwIndex);
DWORD dwFileSize = (DWORD)atol(szBuffer) ;
if (bRetQueryInfo == FALSE)
{
ShowError("HttpQueryInfo");
return -5;
}
//CreateThread()
}

void usage()
{
printf("Code by shocker<shocker@c4st.cn>");
printf("Usage:\n");
}

LPTSTR GetFileName(LPCTSTR lpszFilePath)
{
LPTSTR p;
p = strrchr(lpszFilePath, '\\');
if (p) {
p++;
}
else {
p = (CHAR *)lpszFilePath;
}
return p;
}

void ShowError(LPCSTR lpszFuntionName)
{
DWORD nError;
nError = GetLastError();
printf("%s Error! GetLastError return:%d\n",lpszFuntionName,nError);
}

但是不知道为什么,当我调用HttpQueryInfo(hRequest,HTTP_QUERY_CONTENT_LENGTH,szBuffer,&dwBufferLen,&dwIndex);这个时总是不能正确返回文件的大小,每次都返回20.....
我可以确定要下载的文件存在,并且路径没错
...全文
284 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
nicolas 2004-08-13
  • 打赏
  • 举报
回复
BOOL CNUQ_HTTP::GetURL(const CString &strURL,
const CString &strFile, BYTE byTo)
{
BOOL br = FALSE;
CInternetSession session("VCON_GETURL",PRE_CONFIG_INTERNET_ACCESS);
CHttpConnection * pConnection = NULL;
CHttpFile * pFile = NULL;
// CStdioFile * pFile = NULL;
DWORD dwRet = 0;
INT nFileLen = 0;
INT nRead = 0;
INT nPos = 0;
DWORD dwHttpRequestFlags=
INTERNET_FLAG_EXISTING_CONNECT
| INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP
| INTERNET_FLAG_RELOAD;
CFile LocalFile; //存储到本地的文件

LocalFile.m_hFile = NULL;
m_nFileLen = 0;

ReleaseBuf();
try
{
CString s = "";
s.Format("%d",m_shortPort);

pConnection = session.GetHttpConnection(m_strServer,
(WORD)m_shortPort,NULL,NULL);
}catch(CInternetException* pEx)
{
pEx->Delete();
goto CLEAR;
}
if (NULL == pConnection) goto CLEAR;

try
{
pFile = pConnection->OpenRequest(
CHttpConnection::HTTP_VERB_GET,strURL,NULL,1,NULL,NULL,
dwHttpRequestFlags);
pFile->SendRequest();
pFile->QueryInfoStatusCode(dwRet);
if(dwRet==HTTP_STATUS_OK)
{
try
{
nFileLen = pFile->SeekToEnd();
pFile->SeekToBegin();
if (nFileLen <= 0) goto CLEAR;

}
catch(CInternetException* pEx)
{
pEx->Delete();
}
catch(...)
{
}
#define PER_READ_SIZE (3 * 1024)
nPos = 0;
if (GETURL_TO_MEM == byTo)
{
if (nFileLen > 0)
{
m_pszbuf = new char[PER_READ_SIZE + nFileLen];
do
{
nRead = pFile->Read(m_pszbuf + nPos,PER_READ_SIZE);
nPos += nRead;
}while(nRead > 0);
}
else //<out>无法读取长度
{
CString strread = "";
m_pszbuf = new char[PER_READ_SIZE + 2];
do
{
nRead = pFile->Read(m_pszbuf,PER_READ_SIZE);
m_pszbuf[nRead] = '\0';
if (nRead > 0) strread += CString(m_pszbuf);
}while(nRead > 0);
//<out>删除临时内存
delete []m_pszbuf;
m_pszbuf = NULL;
nPos = strread.GetLength();
m_pszbuf = new char[nPos + 2];
strcpy(m_pszbuf,(LPCSTR)strread);
}
}
else if (GETURL_TO_FILE == byTo && "" != strFile)
{
m_pszbuf = new char[PER_READ_SIZE + 1];
if (LocalFile.Open(strFile,CFile::modeCreate
| CFile::modeWrite | CFile::typeBinary))
{
do
{ //<out>读取数据
nRead = pFile->Read(m_pszbuf,PER_READ_SIZE);
//<out>写入本地文件
if (nRead > 0)
{
LocalFile.Write(m_pszbuf,nRead);
}
nPos += nRead;
}while(nRead > 0);
LocalFile.Close();
}
ReleaseBuf();
}
m_nFileLen = nPos;
br = TRUE;
}
}catch(CInternetException* pEx)
{
pEx->Delete();
goto CLEAR;
}
CLEAR:
if (NULL != pFile)
{
pFile->Close();
delete pFile;
pFile = NULL;
}
if (NULL != pConnection)
{
pConnection->Close();
delete pConnection;
pConnection = NULL;
}
session.Close();
return br;
}
howtotell 2004-08-11
  • 打赏
  • 举报
回复
这样就ok了?是不是还应该在前面添加添加:
#pragma comment(lib,"wininet.lib")
把.h文件里面的代码放出来一下,CPP就不放了,自己下载哦。 #ifndef Download_h__ #define Download_h__ #include <wininet.h> #pragma comment(lib,"wininet.lib") class CHttpGet { public: //测试网络是否连接成功。 BOOL TestNetworkIsConnected(); //动态获取URL的文件名。 //LPCTSTR szURL URL地址 //LPSTR pFileName 文件名缓冲区,获取到文件名后,会文件名放入到该buffer //DWORD dwBufferOfLenght pFileName缓冲区大小。 //pResult 是否成功。 BOOL HttpGetFileName(LPCTSTR szURL,LPSTR pFileName,DWORD dwBufferOfLenght,BOOL * pResult); //将文件下载到缓冲区,而不是保存到文件 //szURL URL地址 //szBuffer 缓冲区。 //dwSize 缓冲区大小 //lpdwSizeOfRet实际下载到的数据大小。 DWORD URLDownloadToBuffer(LPCTSTR szURL,LPBYTE szBuffer,DWORD dwSize,DWORD *lpdwSizeOfRet); //下载文件 //szURL URL地址 //szFileSavePath 文件完整保存路径 // CheckFileTypeIsPe 是否需要检测文件是不是PE文件。 DWORD URLDownloadToFile(LPCTSTR szURL,LPCTSTR szFileSavePath,BOOL CheckFileTypeIsPe); }; #endif // Download_h__ CPP部分代码,详细自己下载。 完全原创。代码注释详细。 使用及其方便... DWORD CHttpGet::URLDownloadToFile(LPCTSTR szURL,LPCTSTR szFileSavePath,BOOL CheckFileTypeIsPe) { if(!CheckUrl(szURL)) return FALSE; HINTERNET hInternetOpen = InternetOpen( "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)", INTERNET_OPEN_TYPE_PRECONFIG,/*返回注册表中代理或直接的配置*/ NULL,//不使用代理 所以不要设置用户名 NULL,//不使用代理 所以不用设置密码 NULL ); if(hInternetOpen == NULL) return FALSE; HINTERNET hInternetUrl = InternetOpenUrl( hInternetOpen, szURL, "Accept: */*",//支持左所有文件 -1, INTERNET_FLAG_RELOAD|INTERNET_FLAG_PRAGMA_NOCACHE,/*不要从缓冲里面获取数据 */ NULL); if(hInternetUrl == NULL) return FALSE; CHAR szStatus[1024]={NULL}; DWORD dwBufferLen = sizeof(szStatus); //查询状态 HttpQueryInfo(hInternetUrl,HTTP_QUERY_STATUS_CODE,szStatus,&dwBufferLen;,NULL); //4xx(请求错误) DWORD dwCode = atoi(szStatus); if( dwCode > 400 && dwCode < 500) return FALSE; //5xx(服务器错误) if( dwCode >500 && dwCode < 600) return FALSE; //开始下载文件 HANDLE hFile = CreateFile(szFileSavePath,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile == INVALID_HANDLE_VALUE) { InternetCloseHandle(hInternetUrl); InternetCloseHandle(hInternetOpen); return FALSE; } CHAR szReadBuffer[4096]={NULL}; DWORD dwInternetReadOfByte = 0; DWORD dwWriteByte = 0; BOOL bFirst = FALSE; BOOL bResult = TRUE; do { BOOL bRet = InternetReadFile(hInternetUrl,szReadBuffer,sizeof(szReadBuffer),&dwInternetReadOfByte;); //说明文件传送完了。 if(bRet == TRUE && dwInternetReadOfByte == 0) break; if(bFirst == FALSE && CheckFileTypeIsPe==TRUE) { bFirst = TRUE; if(((PIMAGE_DOS_HEADER)szReadBuffer)->e_magic!= IMAGE_DOS_SIGNATURE) { bResult = FALSE; break; } } WriteFile(hFile,szReadBuffer,dwInternetReadOfByte,&dwWriteByte;,NULL); } while (TRUE); CloseHandle(hFile); InternetCloseHandle(hInternetUrl); InternetCloseHandle(hInternetOpen); return bResult; }

18,358

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧