相信大家都知道WM为了节约,大量的功能都给势弃了,最混帐的就是连接,下载或者上传竟然没有超时功能,这个在客户的投诉里就混蛋了; 所以自写了一个下载,上传,代理的C++代码,当然,有人讲,何必重新写,用WINNET不就OK了吗? 问题是用系统接口,毕竟难以实现我们更理想的需求,如下载到中途,我想做一些小工作,可以暂停或者之类的!我自己写了一个完整的东西,本来是用来玩多套接字HTTP,我现在只给出一点吧,WM还不需要用得着这么复杂的功能。
老生常谈:头文件
- #pragma comment(lib,"note_prj.lib")
-
- #include <Cfgmgrapi.h>
- #include <connmgr.h>
- #include <wininet.h >
- #pragma comment(lib,"wininet.lib")
- #pragma comment(lib, "Aygshell.lib")
- #pragma comment(lib, "cellcore.lib")
哪个有用哪个没用,我懒得整理了;
建立CHttp.h
- #pragma once
-
- #define HTTP_MAX_RECV 6000
-
- #define HTTP_STRING_V "GET %s HTTP/1.0\r\nHost:%s\r\nReferer:%s\r\n
- Cache-Control: no-cache\r\nUser-Agent:Windows Mobile\r\n
- PlatForm:Musicholic(WM)\r\nConnection: Keep-Alive\r\n\r\n"
-
- #define HTTP_PORT 80
-
- typedef struct HttpString
- {
- char* Buffer;
- size_t Count;
- HttpString(const char* value,size_t v)
- {
- Buffer=new char[v];
- memcpy(Buffer,value,v);
- Count=v;
- }
-
- ~HttpString()
- {
- if(Buffer!=NULL)
- delete[] Buffer;
- }
-
- }HTTP_STRING,*PHTTP_STRING;
-
- typedef struct Httpp_Status
- {
- SOCKET Socket;
- short Count;
- BOOL Status;
- Httpp_Status()
- {
- memset(this,0,sizeof(Httpp_Status));
- Socket=INVALID_SOCKET;
- Status=TRUE;
- }
-
- void CloseSocket()
- {
- if(Socket!=INVALID_SOCKET)
- {
- closesocket(Socket);
- Socket=INVALID_SOCKET;
- }
- }
-
- ~Httpp_Status()
- {
- CloseSocket();
- }
- }HTTP_STATUS,*PHTTP_STATUS;
-
- class CHttp
- {
- public:
- CList<PHTTP_STATUS>* List;
-
- private:
-
- CRITICAL_SECTION Section;
- public:
- CHttp(void);
- ~CHttp(void);
-
-
- public:
-
-
-
-
- BOOL GetConnectionState();
-
-
-
-
- BOOL GPRSRasic(BOOL create);
-
-
-
-
- void getUrlMessage(const char* url,char* host,
- char* httpbuf,short* port);
-
-
-
-
- char* Download(const char* url);
-
-
-
-
-
- static DWORD CALLBACK Run(LPVOID lpVoid);
- };
建立CHttp.CPP
- CHttp::CHttp(void)
- {
- ::InitializeCriticalSection(&Section);
-
- WSADATA* wsaData=new WSADATA;
- WSAStartup(MAKEWORD(1,1),wsaData);
- delete wsaData;
-
- List=new CList<PHTTP_STATUS>();
-
- HANDLE thread=CreateThread(NULL,0,Run,this,0,0);
- CloseHandle(thread);
- }
-
- CHttp::~CHttp(void)
- {
- }
-
-
- DWORD CALLBACK CHttp::Run(LPVOID lpVoid)
- {
- CHttp* object=(CHttp*)lpVoid;
- CList<PHTTP_STATUS>* List=object->List;
-
- int index=0;
- POSITION pos=NULL;
-
- Sleep(1500);
- while(TRUE)
- {
- index=0;
- pos=NULL;
- while(index<List->GetCount())
- {
- pos=List->FindIndex( index );
- PHTTP_STATUS obj=List->GetAt( pos );
- if(!obj->Status || obj->Count>10)
- {
- Sleep(500);
- delete obj;
- List->RemoveAt(pos);
- }
- else
- {
- obj->Count++;
- index++;
- }
- }
- ::Sleep(3000);
- }
- }
-
-
-
- BOOL CHttp::GetConnectionState()
- {
- int index=0;
- BOOL create=FALSE;
-
- SOCKADDR_IN* addr=new SOCKADDR_IN;
-
- while(index<2)
- {
- addr->sin_family=AF_INET;
- addr->sin_port=htons(80);
- addr->sin_addr.s_addr = inet_addr ("64.233.189.104");
-
-
- PHTTP_STATUS sockStatus=new HTTP_STATUS;
- sockStatus->Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
-
- List->AddTail(sockStatus);
- if( connect(sockStatus->Socket,(SOCKADDR*)addr,sizeof(SOCKADDR_IN))
- !=SOCKET_ERROR )
- {
- sockStatus->Status=FALSE;
- delete addr;
- return TRUE;
- }
- sockStatus->Status=FALSE;
-
- if(!create)
- {
- ::EnterCriticalSection(&Section);
- create=GPRSRasic(create);
- ::LeaveCriticalSection(&Section);
- }
- if(create)
- {
- Sleep(3000);
- WSADATA* wsaData=new WSADATA;
- WSAStartup(MAKEWORD(1,1),wsaData);
- delete wsaData;
- }
- index++;
- }
- delete addr;
-
- return FALSE;
- }
-
-
- BOOL CHttp::GPRSRasic(BOOL create)
- {
- if(create) return TRUE;
- HANDLE m_hConnMgr=NULL;
- m_hConnMgr = ConnMgrApiReadyEvent();
- if (!m_hConnMgr)
- return FALSE;
- DWORD dwResult = WaitForSingleObject(m_hConnMgr, 3000);
-
- if (m_hConnMgr)
- {
- CloseHandle(m_hConnMgr);
- m_hConnMgr = NULL;
- }
- if (dwResult != WAIT_OBJECT_0)
- {
- return TRUE;
- }
-
- DWORD dwTimeout = 15000;
-
- BOOL bEstaCon = TRUE;
-
- GUID guidNetworkObject;
- DWORD dwIndex = 0;
-
- if (ConnMgrMapURL(L"http://www.google.com", &guidNetworkObject, &dwIndex)
- == E_FAIL)
- {
- bEstaCon = TRUE;
- }
- if(bEstaCon)
- {
-
- CONNMGR_CONNECTIONINFO* ccInfo=new CONNMGR_CONNECTIONINFO;
- memset(ccInfo, 0, sizeof(CONNMGR_CONNECTIONINFO));
- ccInfo->cbSize = sizeof(CONNMGR_CONNECTIONINFO);
- ccInfo->dwParams = CONNMGR_PARAM_GUIDDESTNET;
- ccInfo->dwFlags = CONNMGR_FLAG_PROXY_HTTP;
-
- ccInfo->dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
- ccInfo->bExclusive = FALSE;
- ccInfo->guidDestNet = guidNetworkObject;
- DWORD dwStatus=0;
- if (ConnMgrEstablishConnectionSync
- (ccInfo, &m_hConnMgr,dwTimeout,&dwStatus) != E_FAIL)
- bEstaCon=TRUE;
- else
- bEstaCon=FALSE;
- delete ccInfo;
- }
- if(m_hConnMgr != NULL)
- ConnMgrReleaseConnection(m_hConnMgr, TRUE);
-
- Sleep(15000);
- return TRUE;
- }
-
- void CHttp::getUrlMessage(const char* url,
- char* host,char* httpbuf,short* port)
- {
- char* tmpUrl=new char[strlen(url)+1];
- strcpy(tmpUrl,url);
- char* purl=tmpUrl;
- purl+=7;
- char* tpHost=purl;
- while(*purl && *purl++!=0x2f){}
- purl--;
- *purl=0;
- strcpy(host,tpHost);
-
- *purl=0x2f;
-
- if(httpbuf!=NULL)
- {
- char* pRefener=tmpUrl+strlen(url)-1;
- while(*pRefener!=0x2f){pRefener--;}
- pRefener++;
- *pRefener=0;
- pRefener=NULL;
- sprintf(httpbuf,HTTP_STRING_V,url,host,tmpUrl);
- delete[] tmpUrl;
- }
- tpHost=host;
- tpHost=strstr(host,":");
- if(tpHost!=NULL)
- {
- *tpHost=NULL;
- *tpHost++;
- *port=atoi(tpHost);
- }
- }
-
- char* CHttp::Download(const char* url)
- {
- if(url==NULL || strlen(url)<10)return NULL;
-
- if(!GetConnectionState() )return NULL;
-
- char* host=new char[50];
- char* httpbuf=new char[700];
- short port=HTTP_PORT;
- memset(host,0,50);
- memset(httpbuf,0,700);
-
- getUrlMessage(url,host,httpbuf,&port);
-
- DWORD dwIPAddr=inet_addr(host);
- hostent* phostent=NULL;
- if(dwIPAddr==INADDR_NONE)
- phostent=gethostbyname(host);
-
- delete[] host;
-
-
- if (phostent==NULL && dwIPAddr==INADDR_NONE)
- {
- delete[] httpbuf;
- return NULL;
- }
-
- SOCKADDR_IN addr;
- addr.sin_family=AF_INET;
- addr.sin_port=htons(port);
- if(dwIPAddr==INADDR_NONE)
- memmove(&addr.sin_addr,phostent->h_addr_list[0],
- sizeof(phostent->h_addr_list[0]));
- else
- addr.sin_addr.S_un.S_addr=dwIPAddr;
-
- PHTTP_STATUS sockStatus=new HTTP_STATUS;
- sockStatus->Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
-
-
- List->AddTail(sockStatus);
-
- if (sockStatus->Socket==INVALID_SOCKET
- || connect(sockStatus->Socket,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR
- || !sockStatus->Status)
- {
- sockStatus->Status=FALSE;
- delete[] httpbuf;
- return NULL;
- }
-
- sockStatus->Count=0;
-
-
- int sen=send(sockStatus->Socket,httpbuf,strlen(httpbuf)+1,0);
-
- delete[] httpbuf;
-
- char* rcvbuf=new char[HTTP_MAX_RECV];
- int nRcv=recv(sockStatus->Socket,rcvbuf,HTTP_MAX_RECV,0);
- if (nRcv < 100 || !sockStatus->Status)
- {
- delete[] rcvbuf;
- return false;
- }
-
- sockStatus->Count=0;
-
- char* p=rcvbuf+20;
- int startChar=20;
- int removeInt=1;
- while(*p++)
- {
- startChar++;
- if (*(p-3)=='\r' && *(p-2)=='\n' && *(p-1)=='\r' && *p=='\n')
- {
- p++;
- break;
- }
- }
-
- CList<PHTTP_STRING>* string=new CList<PHTTP_STRING>();
- string->AddTail( new HTTP_STRING(p,nRcv-startChar-removeInt));
- size_t litCount=nRcv-startChar-removeInt;
-
-
- while(sockStatus->Status)
- {
- memset(rcvbuf,0,HTTP_MAX_RECV);
- nRcv=recv(sockStatus->Socket,rcvbuf,HTTP_MAX_RECV,0);
- sockStatus->Count=0;
-
- if (nRcv<1)break;
-
- litCount+=nRcv;
- string->AddTail( new HTTP_STRING(rcvbuf,nRcv) );
- }
- delete[] rcvbuf;
-
- char* Buffer =(char*)malloc(sizeof(char) * litCount);
- p=Buffer;
- for(POSITION pos=string->GetHeadPosition();pos!=NULL;string->GetNext(pos))
- {
- PHTTP_STRING obj=string->GetAt(pos);
- memcpy(p,obj->Buffer,obj->Count);
- p+=obj->Count;
- delete obj;
- }
- string->RemoveAll();
- delete string;
- sockStatus->Status=FALSE;
-
- return Buffer;
- }
使用:
- CHttp http;
- char* buffer=http.Download("http://www.rosoo.net/");
- free(buffer);
内存方面我尽量做到自我释放,我发现玩WM的C++,对内存的使用真的要十分小心
(yanql) |