我想写一个多线程下载的命令行程序。但是在使用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<[email protected]>");
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.....
我可以确定要下载的文件存在,并且路径没错
源代码如下
#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<[email protected]>");
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.....
我可以确定要下载的文件存在,并且路径没错
#pragma comment(lib,"wininet.lib")
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;
}