- #pragma once
- /*
- * HttpClient同步类
- * 暂时只实现[方案二]
- * 使用[方案一]:
- * #include "SyncHttpClient.h"
- * int main()
- * {
- * CSyncHttpClient syncClient;
- * BYTE pData[1024];
- * uint16 uSize = 1024;
- * syncClient.SetHost(TEXT("192.168.1.1"));
- * syncClient.SetPort(8000);
- * syncClient.SetProgram(TEXT("/program")); //.............or use default
- * if(syncClient.Request(pData, uSize))
- * {
- * BYTE *bRcvBuf = NULL;
- * uint16 uBufSize = 4069;
- * uint16 uPerTime = 512;
- *
- * if(syscClient.QueryContentLength(&uBufSize))
- * {
- * try{
- * bRcvBuf = new BYTE[nBufSize];
- * }
- * catch(...)
- * {
- * return;
- * }
- * if(syncClient.GetResponse(bRcvBuf, uBufSize, uPerTime))
- * {
- * //deal the data
- * delete []bRcvBuf;
- * }
- * }
- * }
- * }
- * [方案二]:
- * #include "SyncHTTPClient.h"
- * class CClientTest:IDataSubscriber
- * {
- * public:
- * //收到数据包
- * virtual void OnPacketReceived(void *pData, UINT16 uSize){//dealit};
- * //数据进度
- * virtual void OnRecvDataPercent(IN BYTE nPercent){//update progress};
- * //数据接收出错
- * virtual void OnRcvError(IN INT16 nError){//report for error};
- * };
- *
- * int DoRequest(void *pData, short uLen)
- * {
- * CClientTest test;
- * CNetDataAdapter ada(test); //ada回主动找CConnectionManager要host等的配置
- * ada.Request(pData, uLen);
- * return 0;
- * }
- *
- */
- #include <wininet.h>
- #include "DataInterface.h"
- #define _DEFAULT_HOST TEXT("192.168.1.10")
- #define _DEFAULT_PORT 80
- #define _DEFAULT_PROG TEXT("/test")
- #define _DEFAULT_MAX_RCV_BUF_SIZE 8192 * 20
- #define _DEFAULT_RECV_BUF_UNIT 4096
- #define _DEFAULT_REFERER_LENGTH 30
- class CAsyncHttpClient :IDataCommunicater
- {
- friend class CConnectManager;
- public:
- enum
- {
- STATUS_LAZY = 0, //空闲
- STATUS_BUSING, //忙
- STATUS_FINISH //结束
- };
- enum
- {
- ERR_MEMORY_EXPRESS = -100, //内存过大,超过m_dwMaxSize限制
- ERR_MEMORY_HEAP_FAILED, //HeapCreate失败
- ERR_INET_OPEN_FAILED, //InternetOpen失败
- ERR_INET_CONNECT_FAILED, //InternetConnect失败
- ERR_INET_REQUEST_FAILED, //HttpOpenRequest失败
- ERR_INET_RESPONSE, //返回不为200
- ERR_INET_CONTENT_LENGTH, //无法得到长度
- ERR_INET_READ, //读数据出错
- ERR_INET_FINISH = 0, //没有错误
- ERR_INET_START //开始
- };
- public:
- CAsyncHttpClient(void);
- ~CAsyncHttpClient(void);
- //post对象配置
- public:
- //设置主机
- void SetPostHost(const TCHAR* szHost = _DEFAULT_HOST);
- //设置主机端口
- void SetHostPort(unsigned short uPort = _DEFAULT_PORT);
- //设置程序
- void SetPostProgram(const TCHAR* szProgram = _DEFAULT_PROG);
- //设置Session,通常一个程序只需要一个Session,即InternetOpen返回的句柄
- void SetSession(HINTERNET hSession = 0);
- //IDataCommunicater接口
- public:
- //注册订阅者
- virtual bool RegisterSubscriber(HWND aSubscriber);
- //取消订阅者
- virtual bool RemoveSubscirber(HWND aSubscriber);
- //是否繁忙
- virtual bool IsBusy() const;
- //发送流
- virtual bool Request(void* aData, DWORD uSize);
- //get请法
- virtual bool HttpGet(TCHAR* szFile);
- //取消发送
- virtual void Cancel();
- //销毁资源
- virtual void Close();
- private:
- void OnWork();
- //状态回调函数
- private:
- static void CALLBACK StatusCallback(HINTERNET hInternet,
- DWORD_PTR dwContext,
- DWORD dwInternetStatus,
- LPVOID lpvStatusInformation,
- DWORD dwStatusInformationLength);
- //数据读取例程
- static DWORD CALLBACK ThreadEntry(LPVOID pThis);
- //辅助函数
- private:
- //判断内存是否足够,不足按指定的粒度分配
- bool EnsureEnoughSpace(DWORD dwRequired = 0);
- //释放内存资源
- void ReleaseResource();
- //完成请求
- void SetCompleteRequest();
- //等待完成请求
- bool WaitCompleteRequest(unsigned long ntime=INFINITE);
- //状态机转换
- bool SetState(short uState);
- short GetState();
- //设置进度条
- void SetProgress(int nStep);
- //创建读数据线程
- void BeginAsyncRead();
- //主机信息与缓存
- private:
- //主机 ip/name
- TCHAR* m_pszHost;
- //端口
- unsigned short m_uPort;
- //程序
- TCHAR* m_pszProg;
- //缓冲区
- const char* m_pData;
- DWORD m_dwContentSize;
- //最大容量,超过此容量,会自动分配
- DWORD m_dwMaxSize;
- //单元容量,当内存不足时,按此容量增加分配
- DWORD m_dwUnitSize;
- //当前容量
- DWORD m_dwCurSize;
- //服务状态
- private:
- //服务正所处的状态
- //InternetOpen
- //InternetConnect
- //HttpOpenRequest
- //HttpAddRequestHeaders
- //HttpSendRequest
- //HttpQueryInfo 查询是否成功
- // 读数据长度
- //InternetReadFile 读数据
- // 重新分配缓存
- // 处理完毕
- short m_uSeviceState;
- HINTERNET _hSession;
- HINTERNET _hConn;
- HINTERNET _hRequest;
- bool _bCloseSession; //如果不是公用的(SetSession),则要关闭
- //订阅客户
- private:
- //订阅数据的客户,目前只支持一个订阅者
- HWND m_pCS;
- //堆内存管理
- private:
- //heap堆句柄
- HANDLE _hHeap;
- //同步事件,请求已完成
- HANDLE _hCompleteRequestEvent;
- //提取数据线程句柄
- HANDLE _hThread;
- DWORD _dwThreadID;
- int m_nPercents;
- };
- #include "StdAfx.h"
- #include "AsyncHttpClient.h"
- #define SAFE_DELARRAY(arr) if(arr){delete[] arr;arr = NULL;}
- CAsyncHttpClient::CAsyncHttpClient(void)
- :m_pszHost(NULL)
- ,m_uPort(_DEFAULT_PORT)
- ,m_pszProg(NULL)
- ,m_pData(NULL)
- ,m_dwContentSize(0)
- ,m_dwMaxSize(_DEFAULT_MAX_RCV_BUF_SIZE)
- ,m_dwUnitSize(_DEFAULT_RECV_BUF_UNIT)
- ,m_dwCurSize(0)
- ,m_uSeviceState(STATUS_LAZY)
- ,_hSession(0)
- ,_hConn(0)
- ,_hRequest(0)
- ,_bCloseSession(true)
- ,m_pCS(NULL)
- ,_hHeap(0)
- ,_hCompleteRequestEvent(INVALID_HANDLE_VALUE)
- ,_hThread(INVALID_HANDLE_VALUE)
- ,_dwThreadID(0)
- ,m_nPercents(0)
- {
- }
- CAsyncHttpClient::~CAsyncHttpClient(void)
- {
- Close();
- //释放内存
- ReleaseResource();
- }
- //------------------------------------------------------------------------
- //设置
- //------------------------------------------------------------------------
- //设置主机
- void CAsyncHttpClient::SetPostHost(const TCHAR* szHost/* = _DEFAULT_HOST*/) throw()
- {
- if(m_uSeviceState != STATUS_LAZY)
- {
- return;
- }
- unsigned short uSize = _tcslen(szHost);
- if(uSize == 0){
- return;
- }
- SAFE_DELARRAY(m_pszHost);
- m_pszHost = new TCHAR[uSize+1];
- if(m_pszHost == NULL)
- {
- return;
- }
- CopyMemory(m_pszHost, szHost, sizeof(TCHAR) * uSize);
- m_pszHost[uSize] = '/0';
- return;
- }
- //设置主机端口
- void CAsyncHttpClient::SetHostPort(unsigned short uPort/* = _DEFAULT_PORT*/) throw ()
- {
- if(m_uSeviceState != STATUS_LAZY)
- {
- return;
- }
- m_uPort = uPort;
- return;
- }
- //设置程序
- void CAsyncHttpClient::SetPostProgram(const TCHAR* szProgram/* = _DEFAULT_PROG*/)
- {
- if(m_uSeviceState != STATUS_LAZY)
- {
- return;
- }
- unsigned short uSize = _tcslen(szProgram);
- if(uSize == 0){
- return;
- }
- SAFE_DELARRAY(m_pszProg);
- m_pszProg = new TCHAR[uSize+1];
- if(m_pszProg == NULL)
- {
- return;
- }
- CopyMemory(m_pszProg, szProgram, sizeof(TCHAR) * uSize);
- m_pszProg[uSize] = '/0';
- return;
- }
- //设置Session,通常一个程序只需要一个Session,即InternetOpen返回的句柄
- void CAsyncHttpClient::SetSession(HINTERNET hSession/* = 0*/)
- {
- if(hSession == 0) return;
- if(m_uSeviceState != STATUS_LAZY)
- {
- return;
- }
- _hSession = hSession;
- _bCloseSession = false;
- return;
- }
- //------------------------------------------------------------------------
- //IDataCommunicater接口
- //------------------------------------------------------------------------
- //注册订阅者
- bool CAsyncHttpClient::RegisterSubscriber(HWND aSubscriber)
- {
- if(!aSubscriber) return false;
- m_pCS = aSubscriber;
- return true;
- }
- //取消订阅者
- bool CAsyncHttpClient::RemoveSubscirber(HWND aSubscriber)
- {
- if(aSubscriber != m_pCS) return false;
- m_pCS = NULL;
- return true;
- }
- //是否繁忙
- bool CAsyncHttpClient::IsBusy() const
- {
- return m_uSeviceState != STATUS_LAZY && STATUS_FINISH != m_uSeviceState;
- }
- //发送流
- bool CAsyncHttpClient::Request(void* aData, DWORD uSize)
- {
- if(IsBusy()) return false;
- if(m_pszHost == NULL)
- SetPostHost();
- if(m_uPort == 0)
- SetHostPort();
- if(m_pszProg == NULL)
- SetPostProgram();
- if(_hCompleteRequestEvent == INVALID_HANDLE_VALUE)
- {
- _hCompleteRequestEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- }
- const TCHAR* pszAccepts[] = {L"*/*", NULL};
- TCHAR szReferer[_DEFAULT_REFERER_LENGTH] = {0};
- #ifdef _UNICODE
- wsprintf(szReferer, L"%s:%d", m_pszHost, m_uPort);
- #else
- sprintf(szReferer, "%s:%d", m_pszHost, m_uPort);
- #endif
- m_uSeviceState = STATUS_BUSING;
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_START, 0);
- }
- if(_hSession == NULL)
- {
- //打开
- _hSession = ::InternetOpen(TEXT("Agent")
- ,INTERNET_OPEN_TYPE_PRECONFIG
- ,NULL //从注册表里读代理信息
- ,NULL
- ,INTERNET_FLAG_ASYNC); //异步连接
- if(NULL == _hSession || _hSession == INVALID_HANDLE_VALUE)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_OPEN_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- _bCloseSession = true;
- }
- //设置回调函数
- INTERNET_STATUS_CALLBACK pc=::InternetSetStatusCallback(_hSession, (INTERNET_STATUS_CALLBACK)this->StatusCallback);
- if(pc == INTERNET_INVALID_STATUS_CALLBACK)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_OPEN_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- if(NULL == _hConn)
- {
- //链接
- _hConn = ::InternetConnect(_hSession
- ,m_pszHost
- ,m_uPort //ip and port
- ,L""
- ,L"" //username and pwd
- ,INTERNET_SERVICE_HTTP
- ,0
- ,reinterpret_cast<unsigned long>(this)); //传到回调函数的自定义参数
- if(NULL == _hConn || INVALID_HANDLE_VALUE == _hConn)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_CONNECT_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- }
- //请求网页
- _hRequest = ::HttpOpenRequest(_hConn
- ,L"POST"
- ,m_pszProg
- ,NULL //使用http/1.0
- ,szReferer
- ,pszAccepts //accept */*
- ,INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE
- ,reinterpret_cast<unsigned long>(this));//传到回调函数的自定义参数
- if(NULL == _hRequest || _hRequest==INVALID_HANDLE_VALUE)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- 更改请求头
- //if(FALSE == ::HttpAddRequestHeaders( _hRequest, L"Accept: */*/r/n", _tcslen(L"Accept: */*/r/n"), HTTP_ADDREQ_FLAG_REPLACE))
- //{
- // sError.Format(L"HttpAddRequestHeaders不能打开 NO = %d", GetLastError());
- // ThrowError(sError);
- // goto ERROR_RELEASE;
- //}
- //开始发请求
- static INTERNET_BUFFERS InternetBufferIn = {0};
- InternetBufferIn.dwStructSize = sizeof(INTERNET_BUFFERS);
- InternetBufferIn.Next = NULL;
- InternetBufferIn.lpcszHeader = NULL;
- InternetBufferIn.dwHeadersLength = 0;
- InternetBufferIn.lpvBuffer = aData; //post的数据
- InternetBufferIn.dwBufferLength = uSize; //数据长度
- //发出请求
- if(FALSE == ::HttpSendRequestEx(_hRequest
- ,&InternetBufferIn
- ,NULL
- ,0
- ,reinterpret_cast<unsigned long>(this))
- &&::GetLastError()!=ERROR_IO_PENDING)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- SetProgress(10);
- //等待10s,否则返回失败
- if(WaitCompleteRequest(10 * 1000) == false)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- SetProgress(20);
- //请求结束
- if(!::HttpEndRequest(_hRequest, NULL, 0, reinterpret_cast<unsigned long>(this))
- &&::GetLastError()!=ERROR_IO_PENDING)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- //创建读数据线程
- _hThread = CreateThread(NULL
- , 0
- ,(LPTHREAD_START_ROUTINE)ThreadEntry
- ,LPVOID(this)
- , 0
- ,&_dwThreadID);
- if(_hThread == 0 || _hThread == INVALID_HANDLE_VALUE)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- SetProgress(10);
- return true;
- }
- bool CAsyncHttpClient::HttpGet(TCHAR* szFile)
- {
- if(IsBusy()) return false;
- if(_hCompleteRequestEvent == INVALID_HANDLE_VALUE)
- {
- _hCompleteRequestEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
- }
- const TCHAR* pszAccepts[] = {L"*/*", NULL};
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_START, 0);
- }
- if(_hSession == NULL)
- {
- //打开
- _hSession = ::InternetOpen(TEXT("TGUIDE")
- ,INTERNET_OPEN_TYPE_PRECONFIG
- ,NULL //从注册表里读代理信息
- ,NULL
- ,INTERNET_FLAG_ASYNC); //异步连接
- if(NULL == _hSession || _hSession == INVALID_HANDLE_VALUE)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_OPEN_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- _bCloseSession = true;
- }
- //设置回调函数
- INTERNET_STATUS_CALLBACK pc=::InternetSetStatusCallback(_hSession, (INTERNET_STATUS_CALLBACK)this->StatusCallback);
- if(pc == INTERNET_INVALID_STATUS_CALLBACK)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_OPEN_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- if(NULL == (_hRequest = InternetOpenUrl(_hSession
- , szFile //地址
- , NULL //头
- , 0 //头的长度
- , INTERNET_FLAG_RELOAD //标志
- , reinterpret_cast<unsigned long>(this))) &&::GetLastError()!=ERROR_IO_PENDING)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- SetProgress(10);
- //等待10s,否则返回失败
- if(WaitCompleteRequest(10 * 1000) == false)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- SetProgress(20);
- //创建读数据线程
- _hThread = CreateThread(NULL
- , 0
- ,(LPTHREAD_START_ROUTINE)ThreadEntry
- ,LPVOID(this)
- , 0
- ,&_dwThreadID);
- if(_hThread == 0 || _hThread == INVALID_HANDLE_VALUE)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- return false;
- }
- SetProgress(10);
- SetCompleteRequest();
- return true;
- }
- //取消发送
- void CAsyncHttpClient::Cancel()
- {
- if(_hRequest){
- ::InternetCloseHandle(_hRequest);
- _hRequest = 0;
- }
- if(_hConn)
- {
- ::InternetCloseHandle(_hConn);
- _hConn = 0;
- }
- //如果任务未完成,就取消,则要重置缓冲区,清除接收缓冲区
- //if(1/*STATUS_FINISH != m_uSeviceState*/)
- //{
- // m_dwContentSize = 0;
- // if(m_pData)
- // {
- // ATLASSERT(_hHeap);
- // BOOL bRet = ::HeapFree(_hHeap, HEAP_NO_SERIALIZE, (LPVOID)m_pData);
- // ATLASSERT(bRet);
- // bRet = HeapDestroy(_hHeap);
- // ATLASSERT(bRet);
- // }
- // m_dwCurSize = 0;
- //}
- if(m_pData)
- {
- //ASSERT(_hHeap);
- //BOOL bRet = ::HeapFree(_hHeap, HEAP_NO_SERIALIZE, (LPVOID)m_pData);
- //ASSERT(bRet);
- //bRet = HeapDestroy(_hHeap);
- //ASSERT(bRet);
- SAFE_DELARRAY(m_pData);
- m_dwCurSize = 0;
- m_dwContentSize = 0;
- }
- m_dwContentSize = 0;
- m_uSeviceState = STATUS_LAZY;
- }
- //销毁资源
- void CAsyncHttpClient::Close()
- {
- Cancel();
- if(_bCloseSession && _hSession)
- {
- ::InternetCloseHandle(_hSession);
- _hSession = 0;
- }
- ReleaseResource();
- }
- //------------------------------------------------------------------------
- //实现IWorkThread接口
- //------------------------------------------------------------------------
- void CAsyncHttpClient::OnWork()
- {
- //while(true)
- //{
- //等待发送请求事件,等待10秒
- if(!WaitCompleteRequest(10*1000))
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- goto DO_RELEASE;;
- }
- //获取数据长度
- DWORD dwTotalSize = 0;
- DWORD dwStatusSize = sizeof(dwTotalSize);
- if(FALSE == ::HttpQueryInfo(_hRequest, HTTP_QUERY_CONTENT_LENGTH| HTTP_QUERY_FLAG_NUMBER, &dwTotalSize, &dwStatusSize, 0))
- {
- //if(m_pCS)
- // m_pCS->OnRcvError(ERR_INET_CONTENT_LENGTH);
- }
- //读数据
- DWORD dwPerRead = m_dwUnitSize;
- DWORD dwReaded = 0;
- m_dwContentSize = 0;
- if(!InternetQueryDataAvailable(_hRequest
- ,&dwPerRead
- ,0
- ,0))
- {
- //等数据2秒,否则失败
- if(!WaitCompleteRequest(10*1000))
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- goto DO_RELEASE;;
- }
- }
- if(EnsureEnoughSpace(dwPerRead) == false) goto DO_RELEASE;;
- BYTE bPercent = 0;
- while(::InternetReadFile(_hRequest
- ,(LPVOID)(m_pData + m_dwContentSize)
- ,dwPerRead
- ,&dwReaded))
- {
- if(dwReaded == 0) break;
- m_dwContentSize += dwReaded;
- if(m_dwContentSize + dwPerRead > m_dwMaxSize)
- {
- m_dwContentSize = m_dwMaxSize;
- break;
- }
- if(!InternetQueryDataAvailable(_hRequest
- ,&dwPerRead
- ,0
- ,0))
- {
- //等数据2秒,否则失败
- if(!WaitCompleteRequest(10*1000))
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_INET_REQUEST_FAILED, 0);
- }
- //取消
- Cancel();
- goto DO_RELEASE;
- }
- }
- if(EnsureEnoughSpace(dwPerRead) == false) break;
- }
- m_uSeviceState = STATUS_FINISH;
- //读取完成
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_RESPONSE, (WPARAM)m_pData, (LPARAM)m_dwContentSize);
- }
- DO_RELEASE:
- ;
- //delete this;
- }
- //------------------------------------------------------------------------
- //状态回调函数
- //------------------------------------------------------------------------
- void CAsyncHttpClient::StatusCallback(HINTERNET hInternet,
- DWORD_PTR dwContext,
- DWORD dwInternetStatus,
- LPVOID lpvStatusInformation,
- DWORD dwStatusInformationLength)
- {
- CAsyncHttpClient* pC = (CAsyncHttpClient*)dwContext;
- switch (dwInternetStatus)
- {
- case INTERNET_STATUS_HANDLE_CREATED: //60
- {
- INTERNET_ASYNC_RESULT* res = (INTERNET_ASYNC_RESULT*)lpvStatusInformation;
- pC->_hRequest = (HINTERNET)(res->dwResult);
- }
- break;
- case INTERNET_STATUS_RESOLVING_NAME: //10
- {
- //AfxMessageBox(L"正在解析URL");
- }
- break;
- case INTERNET_STATUS_NAME_RESOLVED: //11
- {
- //AfxMessageBox(L"URL已解析完毕");
- }
- break;
- case INTERNET_STATUS_CONNECTING_TO_SERVER: //20
- {
- //AfxMessageBox(L"正在连接URL");
- }
- break;
- case INTERNET_STATUS_CONNECTED_TO_SERVER: //21
- {
- //AfxMessageBox(L"已连接URL");
- }
- break;
- case INTERNET_STATUS_SENDING_REQUEST: //30
- {
- //AfxMessageBox(L"正在发送请求");
- }
- break;
- case INTERNET_STATUS_REQUEST_SENT: //32
- {
- //unsigned long *pnsent=(unsigned long*)lpvStatusInformation;
- //CString sz;
- //sz.Format(L"已发送%d字节", *pnsent);
- //AfxMessageBox(sz);
- }
- break;
- case INTERNET_STATUS_RECEIVING_RESPONSE: //40
- {
- if(pC)
- pC->SetState(STATUS_BUSING);
- //AfxMessageBox(L"正在等待响应");
- }
- break;
- case INTERNET_STATUS_RESPONSE_RECEIVED: //41
- {
- //AfxMessageBox(L"服务器已经响应");
- }
- break;
- case INTERNET_STATUS_REQUEST_COMPLETE: //100
- {
- if(pC)
- {
- pC->SetCompleteRequest(); //请求完成
- }
- }
- break;
- case INTERNET_STATUS_CLOSING_CONNECTION: //50
- {
- //AfxMessageBox(L"正在关闭连接");
- }
- break;
- case INTERNET_STATUS_CONNECTION_CLOSED: //51
- {
- //AfxMessageBox(L"连接已关闭");
- }
- break;
- case INTERNET_STATUS_HANDLE_CLOSING: //70
- break;
- case INTERNET_STATUS_INTERMEDIATE_RESPONSE: //120
- break;
- case INTERNET_STATUS_REDIRECT: //110
- break;
- case INTERNET_STATUS_STATE_CHANGE: //200
- break;
- default:
- break;
- };
- return;
- }
- //数据读取例程
- DWORD CAsyncHttpClient::ThreadEntry(LPVOID pThis)
- {
- ((CAsyncHttpClient*) pThis)->OnWork();
- return 0;
- }
- //------------------------------------------------------------------------
- //辅助
- //------------------------------------------------------------------------
- //判断内存是否足够,不足按指定的粒度分配
- bool CAsyncHttpClient::EnsureEnoughSpace(DWORD dwRequired /*= 0*/)
- {
- DWORD dwTotalSize = 0;
- //计算内存是否足够
- if(m_dwCurSize - m_dwContentSize >= dwRequired)
- {
- return true;
- }
- else
- {
- //是否超过总大小
- if((m_dwContentSize + dwRequired) > m_dwMaxSize)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_MEMORY_EXPRESS, 0);
- }
- return false;
- }
- //按粒度计算需要的内存大小
- dwTotalSize = m_dwContentSize + dwRequired;
- if(((m_dwContentSize % m_dwUnitSize) + dwRequired) != 0)
- {
- dwTotalSize += m_dwUnitSize;
- }
- if(dwTotalSize > m_dwMaxSize) dwTotalSize = m_dwMaxSize;
- }
- //否则要再增加内存
- //if(_hHeap == NULL)
- //{
- // //获取系统内存页大小
- // SYSTEM_INFO Sysinfo;
- // GetSystemInfo(&Sysinfo);
- // //make a stack which can chang big
- // //alloct memory
- // _hHeap = HeapCreate(HEAP_NO_SERIALIZE, Sysinfo.dwPageSize, 0);
- // if(0 == _hHeap)
- // {
- // if(m_pCS)
- // {
- // PostMessage(m_pCS, WM_STATUS, ERR_MEMORY_HEAP_FAILED, 0);
- // }
- // return false;
- // }
- //}
- LPVOID pData = NULL;
- try
- {
- if(m_pData == NULL) //第一次分配
- {
- //pData = ::HeapAlloc(_hHeap
- // ,HEAP_ZERO_MEMORY
- // ,dwTotalSize);
- pData = new char[dwTotalSize];
- if(pData == NULL)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_MEMORY_HEAP_FAILED, 0);
- }
- return false;
- }
- m_dwCurSize = dwTotalSize;
- }else{ //重新分配
- //pData = HeapReAlloc(_hHeap, HEAP_ZERO_MEMORY, (LPVOID)m_pData, dwTotalSize);
- pData = new char[dwTotalSize];
- if(pData == NULL)
- {
- if(m_pCS)
- {
- PostMessage(m_pCS, WM_STATUS, ERR_MEMORY_HEAP_FAILED, 0);
- }
- return false;
- }
- memmove(pData, m_pData, m_dwContentSize);
- delete[] m_pData;
- m_dwCurSize = dwTotalSize;
- }
- }
- catch(...)
- {
- return false;
- }
- m_pData = (char*)pData;
- return true;
- }
- //释放内存资源
- void CAsyncHttpClient::ReleaseResource()
- {
- SAFE_DELARRAY(m_pszHost);
- SAFE_DELARRAY(m_pszProg);
- //SAFE_DELARRAY(m_pData);
- if(m_pData)
- {
- //ASSERT(_hHeap);
- //BOOL bRet = ::HeapFree(_hHeap, HEAP_NO_SERIALIZE, (LPVOID)m_pData);
- //ASSERT(bRet);
- //bRet = HeapDestroy(_hHeap);
- //ASSERT(bRet);
- SAFE_DELARRAY(m_pData);
- m_pData = NULL;
- m_dwCurSize = 0;
- m_dwContentSize = 0;
- }
- if(_hCompleteRequestEvent != INVALID_HANDLE_VALUE)
- {
- ::CloseHandle(_hCompleteRequestEvent);
- _hCompleteRequestEvent = INVALID_HANDLE_VALUE;
- }
- }
- //完成请求
- void CAsyncHttpClient::SetCompleteRequest()
- {
- if(_hCompleteRequestEvent !=0 && _hCompleteRequestEvent != INVALID_HANDLE_VALUE)
- ::SetEvent(_hCompleteRequestEvent);
- }
- //等待完成请求
- bool CAsyncHttpClient::WaitCompleteRequest(unsigned long ntime/*=INFINITE*/)
- {
- if(!_hCompleteRequestEvent || _hCompleteRequestEvent==INVALID_HANDLE_VALUE)
- false;
- return ::WaitForSingleObject(_hCompleteRequestEvent, ntime)==WAIT_OBJECT_0? true:false;
- }
- //状态机转换
- bool CAsyncHttpClient::SetState(short uState)
- {
- //if(STATUS_LAZY == m_uSeviceState)
- //{
- // if(uState == STATUS_OPENNED)
- // {
- // m_uSeviceState = uState;
- // }else{
- // return false;
- // }
- //}
- //else if(STATUS_OPENNED == m_uSeviceState)
- //{
- // //if(uState == STATUS_OPENNED || uState == )
- //}
- m_uSeviceState = uState;
- return true;
- }
- short CAsyncHttpClient::GetState()
- {
- return m_uSeviceState;
- }
- void CAsyncHttpClient::SetProgress(int nStep)
- {
- m_nPercents += nStep;
- if(m_nPercents > 100)
- m_nPercents = 100;
- }