http 协议获取文件大小
2012-02-15 16:29
337 查看
转自网络
问题:
我要从http://www.traceboard.com/updatedoc/SetPoint.CAB
下载文件SetPoint.CAB
FhSession=InternetOpen("www.traceboard.com",INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0);
FhConnect=InternetConnect(FhSession,"www.traceboard.com",INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
const char *FAcceptTypes="CAB"; //要下载的文件后缀.CAB
FhRequest=HttpOpenRequest(FhConnect,"GET", CABFile,NULL,RemoteCABFile, &FAcceptTypes,INTERNET_FLAG_RELOAD,0);
HttpSendRequest(FhRequest, NULL, 0, NULL, 0);
DWORD BufLen=sizeof(Buffer);
DWORD dwIndex=0;
bool RetQueryInfo=HttpQueryInfo(FhRequest,HTTP_QUERY_CONTENT_LENGTH, Buffer,&BufLen, &dwIndex);
int FileSize=StrToInt(Buffer);
最后得不到文件大小。。。换文件下载FileSize始终=20
问题出在哪呢?
其他参考:
FhRequest=HttpOpenRequest(FhConnect, "GET", "/updatedoc/SetPoint.CAB", NULL, NULL, (const char**)"*/*\0",INTERNET_FLAG_RELOAD,0);
问题:
我要从http://www.traceboard.com/updatedoc/SetPoint.CAB
下载文件SetPoint.CAB
FhSession=InternetOpen("www.traceboard.com",INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0);
FhConnect=InternetConnect(FhSession,"www.traceboard.com",INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
const char *FAcceptTypes="CAB"; //要下载的文件后缀.CAB
FhRequest=HttpOpenRequest(FhConnect,"GET", CABFile,NULL,RemoteCABFile, &FAcceptTypes,INTERNET_FLAG_RELOAD,0);
HttpSendRequest(FhRequest, NULL, 0, NULL, 0);
DWORD BufLen=sizeof(Buffer);
DWORD dwIndex=0;
bool RetQueryInfo=HttpQueryInfo(FhRequest,HTTP_QUERY_CONTENT_LENGTH, Buffer,&BufLen, &dwIndex);
int FileSize=StrToInt(Buffer);
最后得不到文件大小。。。换文件下载FileSize始终=20
问题出在哪呢?
// HttpSocket.h: interface for the CHttpSocket class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_HTTPSOCKET_H__F49A8F82_A933_41A8_AF47_68FBCAC4ADA6__INCLUDED_) #define AFX_HTTPSOCKET_H__F49A8F82_A933_41A8_AF47_68FBCAC4ADA6__INCLUDED_ #include <afxinet.h> #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CHttpSocket { public: CHttpSocket(); virtual ~CHttpSocket(); int GetServerState();//返回服务器状态码 -1表示不成功 int GetField(const char* szSession,char *szValue,int nMaxLength);//返回某个域值,-1表示不成功 int GetResponseLine(char *pLine,int nMaxLength);//获取返回头的一行 const char* GetResponseHeader(int &Length);//获取完整的返回头 const char *FormatRequestHeader(char *pServer,char *pObject,long &Length, char* pCookie=NULL,char *pReferer=NULL, long nFrom=0,long nTo=0, int nServerType=0);//格式化请求头 int GetRequestHeader(char *pHeader,int nMaxLength) const; BOOL SendRequest(const char* pRequestHeader = NULL,long Length = 0); BOOL SetTimeout(int nTime,int nType=0); long Receive(char* pBuffer,long nMaxLength); BOOL Connect(char* szHostName,int nPort=80); BOOL Socket(); BOOL CloseSocket(); protected: char m_requestheader[1024]; //请求头 char m_ResponseHeader[1024]; //回应头 int m_port; //端口 char m_ipaddr[256]; //IP地址 BOOL m_bConnected; SOCKET m_s; hostent *m_phostent; int m_nCurIndex; //GetResponsLine()函数的游标记录 BOOL m_bResponsed; //是否已经取得了返回头 int m_nResponseHeaderSize; //回应头的大小 }; #endif // !defined(AFX_HTTPSOCKET_H__F49A8F82_A933_41A8_AF47_68FBCAC4ADA6__INCLUDED_)
// HttpSocket.cpp: implementation of the CHttpSocket class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "HttpSocket.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define MAXHEADERSIZE 1024 ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CHttpSocket::CHttpSocket() { m_s=NULL; m_phostent=NULL; m_port=80; m_bConnected=FALSE; for(int i=0;i <256;i++) m_ipaddr[i]='\0'; memset(m_requestheader,0,MAXHEADERSIZE); memset(m_ResponseHeader,0,MAXHEADERSIZE); m_nCurIndex = 0; // m_bResponsed = FALSE; m_nResponseHeaderSize = -1; } CHttpSocket::~CHttpSocket() { CloseSocket(); } BOOL CHttpSocket::Socket() { if(m_bConnected)return FALSE; struct protoent *ppe; ppe=getprotobyname("tcp"); ///创建SOCKET对象 m_s=socket(PF_INET,SOCK_STREAM,ppe->p_proto); if(m_s==INVALID_SOCKET) { TRACE("socket()函数执行失败!\n"); return FALSE; } return TRUE; } BOOL CHttpSocket::Connect(char *szHostName,int nPort) { if(szHostName==NULL) return FALSE; ///若已经连接,则先关闭 if(m_bConnected) { CloseSocket(); } ///保存端口号 m_port=nPort; ///根据主机名获得IP地址 m_phostent=gethostbyname(szHostName); if(m_phostent==NULL) { TRACE("gethostbyname()函数执行失败!\n"); return FALSE; } ///连接 struct in_addr ip_addr; memcpy(&ip_addr,m_phostent->h_addr_list[0],4);///h_addr_list[0]里4个字节,每个字节8位 struct sockaddr_in destaddr; memset((void *)&destaddr,0,sizeof(destaddr)); destaddr.sin_family=AF_INET; destaddr.sin_port=htons(80); destaddr.sin_addr=ip_addr; ///保存主机的IP地址字符串 sprintf(m_ipaddr,"%d.%d.%d.%d", destaddr.sin_addr.S_un.S_un_b.s_b1, destaddr.sin_addr.S_un.S_un_b.s_b2, destaddr.sin_addr.S_un.S_un_b.s_b3, destaddr.sin_addr.S_un.S_un_b.s_b4); if(connect(m_s,(struct sockaddr*)&destaddr,sizeof(destaddr))!=0) { // TRACE(NULL,"connect()函数执行失败!","错误",MB_OK); return FALSE; } ///设置已经连接的标志 m_bConnected=TRUE; return TRUE; } ///根据请求的相对URL输出HTTP请求头 const char *CHttpSocket::FormatRequestHeader(char *pServer,char *pObject, long &Length, char *pCookie,char *pReferer,long nFrom, long nTo,int nServerType) { char szPort[10]; char szTemp[20]; sprintf(szPort,"%d",m_port); memset(m_requestheader,'\0',1024); ///第1行:方法,请求的路径,版本 strcat(m_requestheader,"GET "); strcat(m_requestheader,pObject); strcat(m_requestheader," HTTP/1.1"); strcat(m_requestheader,"\r\n"); ///第2行:主机 strcat(m_requestheader,"Host:"); strcat(m_requestheader,pServer); strcat(m_requestheader,"\r\n"); ///第3行: if(pReferer != NULL) { strcat(m_requestheader,"Referer:"); strcat(m_requestheader,pReferer); strcat(m_requestheader,"\r\n"); } ///第4行:接收的数据类型 strcat(m_requestheader,"Accept:*/*"); strcat(m_requestheader,"\r\n"); ///第5行:浏览器类型 strcat(m_requestheader,"User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)"); strcat(m_requestheader,"\r\n"); ///第6行:连接设置,保持 strcat(m_requestheader,"Connection:Keep-Alive"); strcat(m_requestheader,"\r\n"); ///第7行:Cookie. if(pCookie != NULL) { strcat(m_requestheader,"Set Cookie:0"); strcat(m_requestheader,pCookie); strcat(m_requestheader,"\r\n"); } ///第8行:请求的数据起始字节位置(断点续传的关键) if(nFrom > 0) { strcat(m_requestheader,"Range: bytes="); _ltoa(nFrom,szTemp,10); strcat(m_requestheader,szTemp); strcat(m_requestheader,"-"); if(nTo > nFrom) { _ltoa(nTo,szTemp,10); strcat(m_requestheader,szTemp); } strcat(m_requestheader,"\r\n"); } ///最后一行:空行 strcat(m_requestheader,"\r\n"); ///返回结果 Length=strlen(m_requestheader); return m_requestheader; } ///发送请求头 BOOL CHttpSocket::SendRequest(const char *pRequestHeader, long Length) { if(!m_bConnected)return FALSE; if(pRequestHeader==NULL) pRequestHeader=m_requestheader; if(Length==0) Length=strlen(m_requestheader); if(send(m_s,pRequestHeader,Length,0)==SOCKET_ERROR) { TRACE("send()函数执行失败!\n"); return FALSE; } int nLength; GetResponseHeader(nLength); return TRUE; } long CHttpSocket::Receive(char* pBuffer,long nMaxLength) { if(!m_bConnected)return NULL; ///接收数据 long nLength; nLength=recv(m_s,pBuffer,nMaxLength,0); if(nLength <= 0) { //MessageBox(NULL,"recv()函数执行失败!","错误",MB_OK); CloseSocket(); } return nLength; } ///关闭套接字 BOOL CHttpSocket::CloseSocket() { if(m_s != NULL) { if(closesocket(m_s)==SOCKET_ERROR) { TRACE("closesocket()函数执行失败!\n"); return FALSE; } } m_s = NULL; m_bConnected=FALSE; return TRUE; } int CHttpSocket::GetRequestHeader(char *pHeader, int nMaxLength) const { int nLength; if(int(strlen(m_requestheader))>nMaxLength) { nLength=nMaxLength; } else { nLength=strlen(m_requestheader); } memcpy(pHeader,m_requestheader,nLength); return nLength; } //设置接收或者发送的最长时间 BOOL CHttpSocket::SetTimeout(int nTime, int nType) { if(nType == 0) { nType = SO_RCVTIMEO; } else { nType = SO_SNDTIMEO; } DWORD dwErr; dwErr=setsockopt(m_s,SOL_SOCKET,nType,(char*)&nTime,sizeof(nTime)); if(dwErr) { TRACE("setsockopt()函数执行失败!\n"); return FALSE; } return TRUE; } //获取HTTP请求的返回头 const char* CHttpSocket::GetResponseHeader(int &nLength) { if(!m_bResponsed) { char c = 0; int nIndex = 0; BOOL bEndResponse = FALSE; while(!bEndResponse && nIndex < MAXHEADERSIZE) { recv(m_s,&c,1,0); m_ResponseHeader[nIndex++] = c; if(nIndex >= 4) { if(m_ResponseHeader[nIndex - 4] == '\r' && m_ResponseHeader[nIndex - 3] == '\n' && m_ResponseHeader[nIndex - 2] == '\r' && m_ResponseHeader[nIndex - 1] == '\n') bEndResponse = TRUE; } } m_nResponseHeaderSize = nIndex; m_bResponsed = TRUE; } nLength = m_nResponseHeaderSize; return m_ResponseHeader; } //返回HTTP响应头中的一行. int CHttpSocket::GetResponseLine(char *pLine, int nMaxLength) { if(m_nCurIndex >= m_nResponseHeaderSize) { m_nCurIndex = 0; return -1; } int nIndex = 0; char c = 0; do { c = m_ResponseHeader[m_nCurIndex++]; pLine[nIndex++] = c; } while(c != '\n' && m_nCurIndex < m_nResponseHeaderSize && nIndex < nMaxLength); return nIndex; } int CHttpSocket::GetField(const char *szSession, char *szValue, int nMaxLength) { //取得某个域值 if(!m_bResponsed) return -1; CString strRespons; strRespons = m_ResponseHeader; int nPos = -1; nPos = strRespons.Find(szSession,0); if(nPos != -1) { nPos += strlen(szSession); nPos += 2; int nCr = strRespons.Find("\r\n",nPos); CString strValue = strRespons.Mid(nPos,nCr - nPos); strcpy(szValue,strValue); return (nCr - nPos); } else { return -1; } } int CHttpSocket::GetServerState() { //若没有取得响应头,返回失败 if(!m_bResponsed) return -1; char szState[3]; szState[0] = m_ResponseHeader[9]; szState[1] = m_ResponseHeader[10]; szState[2] = m_ResponseHeader[11]; return atoi(szState); }
//下载子线程 DWORD WINAPI DownLoadIIS(LPVOID lParam) { DOWNLOADIIS_INFO *pIIS = (DOWNLOADIIS_INFO *)lParam; if(pIIS->pAttrib->bDownload || pIIS->pAttrib->sDownloadAddr =="") { delete pIIS; return -1; } char szPath[256] = "\0"; GetCurrentDirectory(256,szPath); strcat(szPath,"\\Archive\\"); char strFilePath[256] = "\0"; wsprintf(strFilePath,"%s%d.rar",szPath,pIIS->nIndex); CHttpSocket HttpSocket; CString strServer,strObject; unsigned short nPort; DWORD dwServiceType; long nLength; const char *pRequestHeader = NULL; AfxParseURL(pIIS->pAttrib->sDownloadAddr,dwServiceType,strServer,strObject,nPort); pRequestHeader = HttpSocket.FormatRequestHeader((LPTSTR)(LPCTSTR)strServer,(LPTSTR)(LPCTSTR)strObject,nLength); if(!HttpSocket.Socket()) { TRACE("创建服务器连接出错!\n"); delete pIIS; return -1; } HttpSocket.SetTimeout(16000,0); if(!HttpSocket.Connect((LPTSTR)(LPCTSTR)strServer,nPort)) { TRACE("连接服务器出错\n"); delete pIIS; return -1; } if(!HttpSocket.SendRequest()) { TRACE("发送请求出错\n"); delete pIIS; return -1; } int nLineSize = 0; char szValue[30]; HttpSocket.GetField("Content-Length",szValue,30); int nSvrState = HttpSocket.GetServerState(); //服务器状态 if(nSvrState == 404) { delete pIIS; return -1; } int nFileSize = atoi(szValue);//URL文件的长度 int nCompletedSize = 0; CFile File; File.Open(strFilePath,CFile::modeCreate | CFile::modeWrite); char pData[1024]; int nReceSize = 0; DWORD dwStartTime,dwEndTime; while(nCompletedSize < nFileSize) { dwStartTime = GetTickCount(); nReceSize = HttpSocket.Receive(pData,1024); if(nReceSize == 0) { TRACE("服务器已经关闭连接\n"); delete pIIS; return -1; } if(nReceSize == -1) { TRACE("接收数据超时.\n"); delete pIIS; return -1; } dwEndTime = GetTickCount(); File.Write(pData,nReceSize); nCompletedSize += nReceSize; } File.Close();////////////////////////////////////////////////////////////////////
其他参考:
FhRequest=HttpOpenRequest(FhConnect, "GET", "/updatedoc/SetPoint.CAB", NULL, NULL, (const char**)"*/*\0",INTERNET_FLAG_RELOAD,0);
相关文章推荐
- ios (ASIHTTPRequest)获取下载文件大小(size)
- QT之HTTP下载获取文件大小信息
- Qt 之 HTTP 请求 多线程分块下载——上(获取下载文件大小)
- linux下C获取文件的大小http://blog.csdn.net/gdujian0119/article/details/6363574
- ios开发 - 获取从http上下载文件的大小
- ios (ASIHTTPRequest)获取下载文件大小(size)
- C#获取文件夹/文件的大小以及占用空间 转摘自:http://www.cnblogs.com/chenpeng-dota/articles/2176470.html
- LINUX C获取文件大小 http://my.oschina.net/mavericsoung/blog/138769
- 获取HTTP 头中响应请求文件的大小
- 关于inputStream.available()与HttpURLConnection.getContentLength()方法获取下载文件的大小
- Http协议之获取自定义文件Head信息(2)
- ios (ASIHTTPRequest)获取下载资源文件大小
- Android HttpURLConnection 获取下载文件大小
- 从HTTP和FTP上获取单个文件的大小
- ios (ASIHTTPRequest)获取下载文件大小(size)
- 通过wget获取 http、ftp 文件大小
- 获取HTTP 头中响应请求文件的大小
- Http协议之获取自定义文件Head信息(1)
- C# 通过HttpWebRequest 创建连接获取文件大小 判断Http类型的文件是否存在
- 获取HTTP头协议中状态值和数据大小