HttpReader

头文件:

#pragma once

#include <afxinet.h>

class CSF_HttpDataReader
{
public:
    CSF_HttpDataReader(void);
    ~CSF_HttpDataReader(void);

public:
    int GetHttpData(CString strUrl,char* buf,int bufSize, int tc = 0);
};

源文件:

#include "StdAfx.h"
#include "SF_HttpDataReader.h"

CSF_HttpDataReader::CSF_HttpDataReader(void)
{
}


CSF_HttpDataReader::~CSF_HttpDataReader(void)
{
}


typedef struct tagASYNC_HTTP_CONTEXT
{
    HANDLE hEvent;
    CString strUrl;
    char* buf;
    int bufSize;

    int nRead;
}ASYNC_HTTP_CONTEXT;


UINT ThreadProc_HttpRead(LPVOID lpParam)
{
    ASYNC_HTTP_CONTEXT* pCon = (ASYNC_HTTP_CONTEXT*)lpParam;

    int nLen;
    int nRead = 0;

    CInternetSession ss(L"HttpClient",1,INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_DONT_CACHE);
    CHttpFile* pFile = NULL;
    try
    {
        pFile = (CHttpFile*)ss.OpenURL(pCon->strUrl, 1, 
            INTERNET_FLAG_TRANSFER_ASCII|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_COOKIES);
        //pFile = (CHttpFile*)ss.OpenURL(pCon->strUrl);
        //pFile = (CHttpFile*)ss.OpenURL(pCon->strUrl, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE);

        if (pFile != NULL)
        {
            DWORD dwStatus;
            //DWORD dwStatusSize = sizeof(DWORD);
            //BOOL bOk = pFile->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER)
            pFile->QueryInfoStatusCode(dwStatus);
            if (HTTP_STATUS_OK == dwStatus)
            {
                while ((nLen = pFile->Read(pCon->buf,4096)) > 0)
                {
                    pCon->buf += nLen;
                    nRead += nLen;
                    if (nRead >= pCon->bufSize)
                    {
                        //Maybe the buffer is too small
                        break;
                    }
                }
            }
            ss.Close();
            pFile->Close();
            delete pFile;
        }
    }
    catch (...)
    {
        pCon->nRead = 0;
    }

    pCon->nRead = nRead;
    SetEvent(pCon->hEvent);

    return 0;
}

int CSF_HttpDataReader::GetHttpData(CString strUrl,char* buf,int bufSize, int tc /* = 0 */)
{
    ASYNC_HTTP_CONTEXT con;
    con.strUrl = strUrl;
    con.buf = buf;
    con.bufSize = bufSize;
    con.nRead = 0;
    con.hEvent = CreateEvent(NULL, FALSE, FALSE, L"");

    if (tc == 0)
    {
        ThreadProc_HttpRead(&con);
    }
    else
    {
        CWinThread* thd = AfxBeginThread(ThreadProc_HttpRead, &con);
        DWORD dwWait = WaitForSingleObject(con.hEvent, tc*1000);
        if (dwWait == WAIT_TIMEOUT)
        {
            TerminateThread(thd->m_hThread, 0);
        }
    }
    
    CloseHandle(con.hEvent);

    return con.nRead;
}

Timeout方法比较凶狠,容易导致泄露。

原文地址:https://www.cnblogs.com/ibearpig/p/3633572.html