头文件:
#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方法比较凶狠,容易导致泄露。