我要从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问题出在哪呢?

解决方案 »

  1.   

    HTTP也有部分是无法取得文件长度的。
      

  2.   

    可是我直接输入这个地址http://www.traceboard.com/updatedoc/SetPoint.CAB 提示下载的时候是会显示文件大小的,要怎么取到呢?
      

  3.   

    DWORD buffer = 0;
    DWORD BufLen = sizeof(buffer);

    bool RetQueryInfo = HttpQueryInfo(FhRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER(LPVOID)&Buffer, &BufLen, NULL);
      

  4.   

    回jameshooo :
    我试过了,debug下文件变了看Buffer的值都不变的。:(还是不行
      

  5.   

    需要去解析http协议的头部 例如 Content-Length:12203  给lz一个类,解析的// 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_)
      

  6.   


    // 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);
    }
      

  7.   

    我之前项目用的.代码没动.//下载子线程
    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();
      

  8.   

    FhRequest=HttpOpenRequest(FhConnect, "GET", RemoteCABFile ,NULL, NULL, (const char**)"*/*\0",INTERNET_FLAG_RELOAD,0);
      

  9.   

    FhRequest=HttpOpenRequest(FhConnect, "GET", "/updatedoc/SetPoint.CAB", NULL, NULL, (const char**)"*/*\0",INTERNET_FLAG_RELOAD,0);
      

  10.   

    回:jameshooo 
    我试过了,还是不行。