http 协议获取文件大小

来源:互联网 发布:android 淘宝下拉刷新 编辑:程序博客网 时间:2024/06/11 05:47


转自网络

问题:

我要从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 > 1000class 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);

原创粉丝点击