httpUtil工具类

1、HttpUtil.h



#ifndef __HTTP_UTIL_H__
#define __HTTP_UTIL_H__

#include <time.h>
#include <stdlib.h> 
#include <stdio.h>
#include <atlbase.h> 
#include <map>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <Winsock2.h>
#include <Windows.h>


using namespace std;
#pragma comment(lib, "ws2_32.lib")


//
//
// error codes for socket
//
//
#define  ERR_SOCK_SUCCEED				0 
#define  ERR_SOCK_BASECODE				(30000)
#define  ERR_SOCK_FAIL					ERR_SOCK_BASECODE
#define  ERR_SOCK_CREATE_FAIL			(ERR_SOCK_BASECODE + 1)						
#define  ERR_SOCK_BIND_FAIL				(ERR_SOCK_BASECODE + 2)
#define  ERR_SOCK_LISTEN_FAIL			(ERR_SOCK_BASECODE + 3)
#define  ERR_SOCK_CONNECT_FAIL			(ERR_SOCK_BASECODE + 4)
#define  ERR_SOCK_SEND_FAIL				(ERR_SOCK_BASECODE + 5)
#define  ERR_SOCK_RECV_FAIL				(ERR_SOCK_BASECODE + 6)

#define  ERR_HTTP_SUCCESS				0
#define  ERR_HTTP_BASECODE				(10000)
#define  ERR_HTTP_FAIL					(ERR_HTTP_BASECODE+1)
#define  ERR_HTTP_RES_BODY_INVALID		(ERR_HTTP_BASECODE+2)
#define  ERR_HTTP_GEN_REQDATA_FAIL		(ERR_HTTP_BASECODE+3)
#define  ERR_HTTP_IP_ADDR_INVALID		(ERR_HTTP_BASECODE+4)
#define  ERR_HTTP_STATUS_NOT_200		(ERR_HTTP_BASECODE+5)

//
//
// stl types replacement
//
//
typedef std::map<const std::string, const std::string>   MAP_STRING_STRING;
typedef std::pair<const std::string, const std::string>  PAIR_STRING_STRING;
typedef std::map<const char *, const char *>			 MAP_PCHAR_PCHAR;


//
//
//  CIHttpUtil: abstract class 
//
//
class CIHttpUtil
{
public:
    //set fields
    virtual void SetReqAction(const char *pcAction) = 0;
    virtual void SetReqUri(const char *pcReqUri) = 0;
    virtual void SetReqHttpVer(const char	*pcHttpVer) = 0;
    virtual void SetReqHost(const char	*pcHost) = 0;
    virtual void SetReqField(const char *pcFieldName, const char *pcValue) = 0;
    virtual void SetReqBody(const char *pcReqBody) = 0; 

    //get field value
    virtual string GetReqAction() const = 0;
    virtual string GetReqUri() const = 0;
    virtual string GetReqHttpVer() const = 0;
    virtual string GetReqHost() const = 0;
    virtual string GetReqFieldValue(const char	*pcFieldName) const = 0;
    virtual string GetReqBody() const = 0;

public:
    // actions 
    virtual int GenerateReqData()  = 0;
    virtual int SendReqData(const char *pcIP, unsigned int nPort) = 0;

    //reponse
public:
    virtual const MAP_STRING_STRING &GetResHeaderMap() const = 0;
    virtual string GetResBody() const = 0;
    virtual int HandleResData() = 0;
};



//
//
//  CHttpUtil derived from  CIHttpUtil
//
//
class CHttpUtil:public CIHttpUtil
{
public:
    //construct
    CHttpUtil();
    //destruct
    virtual ~CHttpUtil();

public:

    /*************************************************
    *FUNCTION : set request action
    *[INPUT]  :
    *		pcAction - action method, e.g. POST/GET
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A	
    *************************************************/
    void SetReqAction(const char *pcAction);

    /*************************************************
    *FUNCTION : set uri
    *[INPUT]  :
    *		pcReqUri - uri
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A		
    *************************************************/
    void SetReqUri(const char *pcReqUri);

    /*************************************************
    *FUNCTION : set http version
    *[INPUT]  :
    *		pcHttpVer - http version, e.g. HTTP/1.1
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A		
    *************************************************/
    void SetReqHttpVer(const char	*pcHttpVer);

    /*************************************************
    *FUNCTION : set host 
    *[INPUT]  :
    *		pcHost - host
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A	
    *************************************************/
    void SetReqHost(const char	*pcHost);

    /*************************************************
    *FUNCTION : set request message type
    *[INPUT]  :
    *		pcMsgType - message type
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A	
    *************************************************/
    void SetReqMsgType(const char *pcMsgType);

    /*************************************************
    *FUNCTION : set request token
    *[INPUT]  :
    *		pcToken - token
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A	
    *************************************************/
    void SetReqToken(const char	*pcToken);

    /*************************************************
    *FUNCTION : set field name and value
    *[INPUT]  :
    *		pcFieldName - field name
    *		pcValue - value
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A	
    *************************************************/
    void SetReqField(const char *pcFieldName, const char *pcValue);

    /*************************************************
    *FUNCTION : set request body
    *[INPUT]  :
    *		pcReqBody - request body
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		N/A	
    *************************************************/
    void SetReqBody(const char  *pcReqBody); 

    /*************************************************
    *FUNCTION : get request action
    *[INPUT]  :
    *		sockCon - connecting socket
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqAction() const;

    /*************************************************
    *FUNCTION : get request uri
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqUri() const;

    /*************************************************
    *FUNCTION : get http version
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqHttpVer() const;

    /*************************************************
    *FUNCTION : get host
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqHost() const;

    /*************************************************
    *FUNCTION : get value by field name
    *[INPUT]  :
    *		pcFieldName - field name
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqFieldValue(const char	*pcFieldName) const;

    /*************************************************
    *FUNCTION : get request message type
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqMsgType() const;

    /*************************************************
    *FUNCTION : get request token
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqToken() const;

    /*************************************************
    *FUNCTION : get request body
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqBody() const;

    /*************************************************
    *FUNCTION : get request data including header and body
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		valid string  - succeed           
    *		NULL - empty
    *************************************************/
    string GetReqData() const;

    /*************************************************
    *FUNCTION : generate request data
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		0 - succeed           
    *		others - fail
    *************************************************/
    int GenerateReqData() ;

    /*************************************************
    *FUNCTION : send request data to server
    *[INPUT]  :
    *		pcIP - server ip
    *		nPort - server port
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		>0 - succeed           
    *		others - fail
    *************************************************/
    int SendReqData(const char *pcIP, unsigned int nPort);


    /*************************************************
    *FUNCTION : get response header map
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		map - succeed           
    *		others - fail
    *************************************************/
    const MAP_STRING_STRING &GetResHeaderMap() const ;

    /*************************************************
    *FUNCTION : close socket
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		string value - succeed           
    *		NULL - empty
    *************************************************/
    string	GetResBody() const ;

    /*************************************************
    *FUNCTION : handle response data
    *[INPUT]  :
    *		N/A		
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		0 - succeed           
    *		others - fail
    *************************************************/
    int	HandleResData() ;


public:
    /*************************************************
    *FUNCTION : start up socket
    *[INPUT]  :
    *		N/A	
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		>0 - succeed           
    *		<0 - fail
    *************************************************/
    SOCKET  SOCK_Create();

    /*************************************************
    *FUNCTION : connect with server via socket
    *[INPUT]  :
    *		sockCon - socket to connect with server
    *		pcSrvIP - server ip
    *		uiPort -  server port
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		0 - succeed           
    *		others - fail
    *************************************************/
    int	SOCK_Connect(SOCKET &sockCon, const char *pcSrvIP, unsigned int uiPort);

    /*************************************************
    *FUNCTION : send data via socket
    *[INPUT]  :
    *		sockCon - connecting socket
    *		pcSendBuf - buffer of data to send
    *		nSendLen -  the length of data to send
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		nSendLen - succeed           
    *		other - fail
    *************************************************/
    int	SOCK_Send(SOCKET sockCon, const char *pcSendBuf, int nSendLen );

    /*************************************************
    *FUNCTION : recv data via socket
    *[INPUT]  :
    *		sockCon - connecting socket
    *[OUTPUT] :
    *		pcRecvBuf - buffer of data to recv
    *		pnRecvLen -  the length of data to recv	
    *RETURN   :
    *		>0 - succeed           
    *		<0 - fail
    *************************************************/
    int	SOCK_Recv(SOCKET sockCon,  char *pcRecvBuf, int *pnRecvLen);

    /*************************************************
    *FUNCTION : download data and store in file
    *[INPUT]  :
    *		sockCon - connecting socket
    *		lpwstrSaveFilePath - file path to save download data
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		0 - succeed           
    *		others - fail
    *************************************************/
    int	SOCK_Download(SOCKET sockCon, LPCWSTR lpwstrSaveFilePath);
    int SOCK_DownloadEx(SOCKET sockCon, LPCWSTR lpwstrSaveFilePath);

    /*************************************************
    *FUNCTION : close socket
    *[INPUT]  :
    *		sockCon - connecting socket
    *[OUTPUT] :
    *		N/A		
    *RETURN   :
    *		0 - succeed           
    *		others - fail
    *************************************************/
    int	SOCK_Close(SOCKET sockCon);


private:
    //req header -  common  fields
    string				m_strReqAction;
    string				m_strReqUri;
    string				m_strReqHttpVer;
    string				m_strReqHost; 
    //msg-type, tokn
    string				m_strReqMsgType;
    string				m_strReqToken;

    MAP_STRING_STRING	m_mapReqHeader;
    string				m_strReqHeader;
    string				m_strReqBody;
    string				m_strReqData;

    //res header - common fields
    string				m_strResData;
    //vector<char>		m_vectResDataBuf;
    string				m_strResTopHeader;
    MAP_STRING_STRING	m_mapResHeader;
    string				m_strResHeader;
    string				m_strResBody;

    //xml parse
    string				m_strXMLValue;


};


#endif

2、HttpUtil.cpp

#include "stdafx.h"
#include "HttpUtil.h"

CHttpUtil::CHttpUtil()
{

}
CHttpUtil::~CHttpUtil()
{

}

// req header operations
void CHttpUtil::SetReqAction(const char *pcAction)
{
    if (strlen(pcAction) > 0)
    {
        m_strReqAction = pcAction;
    }
}

void CHttpUtil::SetReqUri(const char * pcReqUri)
{
    if (strlen(pcReqUri) > 0)
    {
        m_strReqUri = pcReqUri;
    }

}

void CHttpUtil::SetReqHttpVer(const char *pcHttpVer)
{
    if (strlen(pcHttpVer) > 0)
    {
        m_strReqHttpVer = pcHttpVer;
    }

}

void CHttpUtil::SetReqHost(const char* pcHost)
{
    if (strlen(pcHost) >0)
    {
        m_strReqHost = pcHost;
    }
}

void CHttpUtil::SetReqMsgType(const char* pcMsgType)
{
    if (strlen(pcMsgType) > 0)
    {
        m_strReqMsgType = pcMsgType;
    }
}
void CHttpUtil::SetReqToken(const char* pcToken)
{
    if (strlen(pcToken) > 0 )
    {
        m_strReqToken = pcToken;
    }

}
void CHttpUtil::SetReqField(const char *pcFieldName, const char *pcValue)
{
    if (strlen(pcFieldName) <= 0 ||  strlen(pcValue) <= 0)
    {
        return ;
    }
    bool fExist = false;
    for (MAP_STRING_STRING::iterator iter = m_mapReqHeader.begin(); iter != m_mapReqHeader.end(); ++iter)
    {
        if (iter->first == pcFieldName)
        {
            fExist = true;
            break;
        }
    }
    if (!fExist)
    {
        m_mapReqHeader.insert(PAIR_STRING_STRING(pcFieldName, pcValue));
    }
}

void CHttpUtil::SetReqBody(const char *pcReqBody) 
{
    if (strlen(pcReqBody) > 0)
    {
        m_strReqBody = pcReqBody;
    }

}

string CHttpUtil::GetReqAction() const
{
    return m_strReqAction;
}

string CHttpUtil::GetReqUri() const
{
    return m_strReqUri;
}
string CHttpUtil::GetReqHttpVer() const
{
    return m_strReqHttpVer;
}

string CHttpUtil::GetReqHost() const
{
    return m_strReqHost;
}
string CHttpUtil::GetReqFieldValue(const char *pcFieldName) const
{
    if (pcFieldName != NULL || strlen(pcFieldName) <= 0)
    {
        return NULL;
    }
    for (MAP_STRING_STRING::const_iterator iter = m_mapReqHeader.begin(); iter != m_mapReqHeader.end(); iter++)
    {
        if (iter->first == pcFieldName)
        {
            return iter->second;
        }
    }

    return NULL;
}

string CHttpUtil::GetReqBody() const
{
    return m_strReqBody;
}


int CHttpUtil::GenerateReqData()
{
    m_strReqData.append(m_strReqAction).append(" ").append(m_strReqUri).append(" ").append("HTTP/1.1").append("\r\n");
    m_strReqData.append("Host:").append(m_strReqHost).append("\r\n");
    m_strReqData.append("Accept:*/*\r\n");
    //append message and Token
    m_strReqData.append("message: ").append(m_strReqMsgType).append("\r\n");
    m_strReqData.append("Token:").append(m_strReqToken).append("\r\n");
    //add Content-Length
    int nReqBodyLen = (int)strlen(m_strReqBody.c_str());
    //if (nReqBodyLen > 0)
    //{
    char pcLenBuf[32] = {0};
    sprintf(pcLenBuf, "%d", nReqBodyLen );
    m_strReqData.append("Content-Length:").append(pcLenBuf).append("\r\n");
    //}
    //m_strReqData.append("Content-Type:application/xml").append("\r\n");
    m_strReqData.append("Accept-language: zh-cn").append("\r\n");
    m_strReqData.append("Accept-Encoding: gzip, deflate").append("\r\n");
    m_strReqData.append("User-Agent: Mozilla/4.0 (compatible; MS IE 6.0; EIS iPanel 2.0;(ziva))").append("\r\n");
    m_strReqData.append("Connection: Keep-Alive").append("\r\n");

    m_strReqData.append("\r\n");
    //append the req body
    m_strReqData.append(m_strReqBody);

    return 0;

}

string CHttpUtil::GetReqData() const
{
    return m_strReqData;
}

//send req data
int CHttpUtil::SendReqData(const char *pcIPAddr, unsigned int uiPort)
{
    if (NULL == pcIPAddr || strlen(pcIPAddr) <=0)
    {
        return ERR_HTTP_IP_ADDR_INVALID;
    }

    int nRet = GenerateReqData();

    if (nRet != 0)
    {
        return  ERR_HTTP_GEN_REQDATA_FAIL;
    }

    int nErrCode = ERR_HTTP_FAIL;

    SOCKET sockCon = SOCK_Create();

    char pcRecvBuf[2048*4] = {0};
    int  nRecvBuf = 2048*4;

    if (INVALID_SOCKET != sockCon)
    {
        nRet = SOCK_Connect(sockCon, pcIPAddr, uiPort);
        if (0 == nRet)
        {
            const char *pcReqData = m_strReqData.c_str() ;
            int nByteSend = m_strReqData.size();
            int nLen = SOCK_Send(sockCon, pcReqData, nByteSend);
            if (nLen <= 0)
            {
                nErrCode = ERR_SOCK_SEND_FAIL;
            }

            nLen = SOCK_Recv(sockCon, pcRecvBuf, &nRecvBuf);
            if (nLen <= 0)
            {
                nErrCode = ERR_SOCK_RECV_FAIL;
            }
            else
            {
                m_strResData = pcRecvBuf;
                nErrCode = ERR_SOCK_SUCCEED;
            }
        }
    }

    return nErrCode;
}

const MAP_STRING_STRING &CHttpUtil::GetResHeaderMap() const
{
    return m_mapResHeader;
}

string CHttpUtil::GetResBody() const
{
    return m_strResBody;
}

int CHttpUtil::HandleResData()
{
    string strTemp = m_strResData;
    // res top header,e.g.  HTTP/1.1 200 OK
    size_t nResTopHeaderPos = strTemp.find("\r\n");
    m_strResTopHeader =  strTemp.substr(0, nResTopHeaderPos - 0);
    if (m_strResTopHeader.find("200") == std::string::npos)
    {
        return ERR_HTTP_STATUS_NOT_200;
    }
    // get res header
    size_t nResHeaderTailPos = strTemp.find("\r\n\r\n");
    m_strResHeader = strTemp.substr(0, nResHeaderTailPos-0);
    //get res body
    m_strResBody = strTemp.substr(nResHeaderTailPos+strlen("\r\n\r\n"));

    return ERR_HTTP_SUCCESS;

}


SOCKET CHttpUtil::SOCK_Create()
{
    //connect to server
    int nRet = ERR_SOCK_FAIL;
    WSADATA wsaData;
    nRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (nRet < 0)
    {
        return -1;
    }

    SOCKET sockCon = INVALID_SOCKET;
    sockCon = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET  == sockCon)
    {
        return -2;
    }

    return sockCon;
}

int  CHttpUtil::SOCK_Connect(SOCKET &sockCon, const char *pcSrvIP, unsigned int uiPort)
{
    int nRet = ERR_SOCK_FAIL;

    SOCKADDR_IN  srvSockAddr;
    memset(&srvSockAddr, 0, sizeof(SOCKADDR_IN));
    srvSockAddr.sin_family = AF_INET;
    srvSockAddr.sin_addr.s_addr = inet_addr(pcSrvIP);
    srvSockAddr.sin_port = htons(uiPort);

    nRet = connect(sockCon, (struct sockaddr*)& srvSockAddr, sizeof(srvSockAddr));
    if (nRet < 0)
    {
        closesocket(sockCon);
        return ERR_SOCK_CONNECT_FAIL;
    }

    return ERR_SOCK_SUCCEED;
}

//send data
int CHttpUtil::SOCK_Send(SOCKET sockCon, const char *pcSendBuf, int nSendLen)
{
    int nRet = ERR_SOCK_FAIL;
    int nSendTempLen = 0;
    int nLeftLen = nSendLen;
    int nSendBlockLen = 1024;

    nRet = send(sockCon, pcSendBuf, nSendLen, 0);

    return nRet;

    /*    while(nLeftLen >0)
    {
    nSendTempLen = send(sockCon, pcSendBuf, nSendBlockLen, 0);
    if (nSendTempLen < 0)
    {
    DWORD dwErr = GetLastError();
    if (WSAEWOULDBLOCK == dwErr)
    {
    continue;
    }

    return dwErr;
    }
    nLeftLen-=nSendTempLen;
    pcSendBuf+=nSendTempLen;
    }

    return nSendLen - nLeftLen;*/
}

//recv data via select modal
int CHttpUtil::SOCK_Recv(SOCKET sockCon,  char *pcRecvBuf, int *pnRecvLen)
{
    //nRet = recv(sockfd, pcRecvBuffer, SOCK_RECV_BUFFER_LEN, 0);

    struct timeval struTimeOut;
    struTimeOut.tv_sec = 5;//wait for 8 seconds
    struTimeOut.tv_usec = 0;
    //use set
    fd_set fdReadSet;
    FD_ZERO(&fdReadSet);
    FD_SET(sockCon, &fdReadSet);

    int nRecvedLen = 0;
    int nTotalLen = 0;
    int nRet = 0;

    nRet = select(NULL, &fdReadSet, NULL, NULL, &struTimeOut);

    switch (nRet)
    {
    case SOCKET_ERROR:
        //return ERR_SOCK_RECV_FAIL;
        break;
    case 0:
        break;
    default:
        {
            while(1)
            {
                nRecvedLen = recv(sockCon, pcRecvBuf, 2048, 0);
                if (  SOCKET_ERROR  == nRecvedLen)
                {
                    return ERR_SOCK_RECV_FAIL;
                }
                else if (0 == nRecvedLen)
                {
                    goto END;
                }
                pcRecvBuf+=nRecvedLen;
                nTotalLen+=nRecvedLen;
                break;
            }
        }
    }
END:
    //recv Async
    if (nTotalLen <= 0)
    {
        return ERR_SOCK_RECV_FAIL;
    }
    *pnRecvLen = nTotalLen;

    return nTotalLen;
}

//recv and save data to local file
int  CHttpUtil::SOCK_Download(SOCKET sockCon, LPCWSTR lpwstrSaveFilePath)
{
    char pcTmpRecvBuf[2048] = {0};
    int  nRet = ERR_SOCK_FAIL;
    int  nTempRecvLen = 0;
    BOOL fIsFirstTime = TRUE;
    int  nRecvedLen = 0;
    long nContentLen = 0;
    int  nHeaderLen = 0;
    int  nTempBodyLen = 0;
    DWORD dwWriten = 0;
    BOOL bRet = FALSE;
    vector<char> vectRecvBuf;//to recv the data 

    char pcResHeaders[2048] = {0};
    char pcResBody[2048] = {0};

    HANDLE hSaveFile = CreateFile(lpwstrSaveFilePath, 
        GENERIC_WRITE|GENERIC_READ, 
        0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE ==hSaveFile)
    {
        return GetLastError();
    }

    while(1)
    {
        nTempRecvLen = recv(sockCon, pcTmpRecvBuf, 2048, 0);
        if (SOCKET_ERROR == nTempRecvLen )
        {
            int nErr = WSAGetLastError();
            if (WSAEWOULDBLOCK == nErr)
            {
                continue;
            }
        }
        else if (0 == nTempRecvLen)
        {
            break;
        }
        //at first time, we will recv the header data
        if (fIsFirstTime)
        {
            vectRecvBuf.resize(nTempRecvLen);
            memcpy(&vectRecvBuf.front(), pcTmpRecvBuf, nTempRecvLen);
            //divid the recved data to headers and body

            string strRecvBuf = pcTmpRecvBuf;
            size_t nPosStart = strRecvBuf.find("Content-Length: "); // Content-Length: 69
            if (string::npos == nPosStart)
            {
                continue;
            }
            nPosStart+=strlen("Content-Length: ");
            string strContentLenField = strRecvBuf.substr(nPosStart);
            nContentLen  = atoi(strContentLenField.c_str());
            size_t nPosHeaderEnd = strRecvBuf.find("\r\n\r\n");
            nHeaderLen = nPosHeaderEnd+strlen("\r\n\r\n");

            nTempBodyLen= nTempRecvLen - nHeaderLen;

            if (nContentLen > nTempBodyLen)
            {

                bRet = WriteFile(hSaveFile, pcTmpRecvBuf+nHeaderLen, nTempBodyLen, &dwWriten, NULL);

                nRecvedLen += nTempBodyLen;
                fIsFirstTime = FALSE;
            }
            else
            {

                bRet =  WriteFile(hSaveFile, pcTmpRecvBuf+nHeaderLen, nTempBodyLen, &dwWriten, NULL);
            }

        }
        else // continue to download the left data without headers
        {
            nRecvedLen+=nTempRecvLen;
            if (nContentLen > nRecvedLen)
            {
                bRet = WriteFile(hSaveFile, pcTmpRecvBuf, nTempRecvLen, &dwWriten, NULL);
                nRecvedLen+=nTempRecvLen;
            }
            else
            {
                bRet = WriteFile(hSaveFile, pcTmpRecvBuf, nTempRecvLen, &dwWriten, NULL);
            }
        }

        SetEndOfFile(hSaveFile);
        ZeroMemory(pcTmpRecvBuf, 2048);
    }

    CloseHandle(hSaveFile);

    return nRecvedLen;
}

//close socket
int  CHttpUtil::SOCK_Close(SOCKET sockCon)
{
    if (sockCon)
    {
        closesocket(sockCon);
    }

    return ERR_SOCK_SUCCEED;
}


int  CHttpUtil::SOCK_DownloadEx(SOCKET sockCon, LPCWSTR lpwstrSaveFilePath)
{
    int  nRet = ERR_SOCK_FAIL;
    char pcTmpRecvBuf[2048] = {0};
    int  nTempRecvLen = 0;
    BOOL boIsFirstTime = TRUE;
    BOOL boRet = FALSE;
    BOOL boContinue = FALSE;
    int  nTotalRecvLen = 0;//total recv length
    int  nContentLen = 0;// 
    int  nHeadersLen = 0;
    int  nTempBodyLen = 0;
    int  nTotalBodyLen = 0;
    DWORD dwWriten = 0;
    vector<char> vectRecvBuf;//to recv the data 
    char pcResHeaders[2048] = {0};
    char pcResBody[2048] = {0};

    HANDLE hSaveFile = CreateFile(lpwstrSaveFilePath, GENERIC_WRITE|GENERIC_READ, 
        0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hSaveFile)
    {
        return GetLastError();
    }

    while(true)
    {
        nTempRecvLen = recv(sockCon, pcTmpRecvBuf, 2048, 0);
        if (SOCKET_ERROR == nTempRecvLen )
        {
            int nErr = WSAGetLastError();
            if (WSAEWOULDBLOCK == nErr)
            {
                continue;
            }
        }
        else if (0 == nTempRecvLen)
        {
            break;
        }
        //at the first time, we will recv the headers 
        if (boIsFirstTime)
        {
            vectRecvBuf.resize(nTempRecvLen);
            char *pRecvBufStart = &vectRecvBuf.front();
            memcpy(pRecvBufStart, pcTmpRecvBuf, nTempRecvLen);
            //divid the recved data to headers and body
            char *pHeadersEnd = strstr(pRecvBufStart, "\r\n\r\n");
            //get the headers
            nHeadersLen = int (pHeadersEnd - pRecvBufStart) + (int)strlen("\r\n\r\n");
            memcpy(pcResHeaders, pRecvBufStart, nHeadersLen);
            //get the body legth
            char *pContentLenField = strstr(pRecvBufStart, "Content-Length: ");
            nContentLen = atoi(pContentLenField+strlen("Content-Length: "));

            nTempBodyLen = nTempRecvLen - nHeadersLen;
            boRet =  WriteFile(hSaveFile, pHeadersEnd+strlen("\r\n\r\n"), nTempBodyLen, &dwWriten, NULL);

            nTotalRecvLen+= nTempRecvLen;
            nTotalBodyLen+=  nTempBodyLen;
            boIsFirstTime = FALSE;
            if (nContentLen > nTempBodyLen)
            {
                boContinue = TRUE;
            }
        }
        else // continue to download the left data without headers
        {
            boRet = WriteFile(hSaveFile, pcTmpRecvBuf, nTempRecvLen, &dwWriten, NULL);

            nTotalRecvLen+=nTempRecvLen;
            nTempBodyLen = nTempRecvLen;
            nTotalBodyLen+=nTempBodyLen;

            if (nContentLen > nTotalRecvLen)
            {
                boContinue = TRUE;
            }
            else
            {
                boContinue = FALSE;
            }
        }

        SetEndOfFile(hSaveFile);
        ZeroMemory(pcTmpRecvBuf, 2048);
    }

    CloseHandle(hSaveFile);

    return nTotalRecvLen;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值