// testHttp003.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" // webrequest.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <string> #include <fstream> #include <winsock2.h> #include <stdio.h> #pragma comment(lib, "WS2_32") using namespace std; namespace DEVWEB { struct ACloseSkt { ACloseSkt(SOCKET h) { m_h = h; } ~ACloseSkt() { if(m_h) closesocket(m_h); m_h = 0; } SOCKET m_h; }; struct RequestParam { bool bPost; //是否为POST请求 const char* pPostData; //为POST数据,需要自已维护内存; unsigned int uiPostLen; //为POST数据长度,主要为了兼容可以上传二进制数据,一般请求就为pPostData字符串长度 const char* pReferer; //请求的引用页面,就是来源页面 const char* pAttachHeader;//附加自定义头 bool bBlock; //true=阻塞式连接,false=异步连接,*******注意:使用异步必须设置超时时间 unsigned int uiTimeout; //异步超时 单位ms RequestParam(){ memset(this,0, sizeof(RequestParam)); bBlock = true; bPost = false; } }; void GetRealIP(string& ip, string& retip) { retip = ip; unsigned long t = inet_addr((char*)(LPCSTR)ip.c_str()); if (t == INADDR_NONE) { hostent* hostInfo = gethostbyname((char*)(LPCSTR)ip.c_str()); if (hostInfo) { struct in_addr *addr; addr = (struct in_addr*)hostInfo->h_addr_list[0]; if(addr!=NULL) { retip = inet_ntoa(*addr); } }else{ printf("GetRealIP can‘t parse domain %s\n",ip.c_str()); } } } ////////////////////////////////////////////////////////////////////////// //szURL 一个完整的URL仅HTTP,HTTPS不支持,可以包含GET参数,如index.php?username=test //response 为请求返回的结果,包含HTTP头信息 //pRP为附加参数,完成更复杂的请求 /////////////////////////////////////////////////////////////////////////// bool WebRequest( const char* szURL, std::string& response, RequestParam* pRP = 0) { if (!szURL ) return false; WORD wVersionRequested; WSADATA wsaData; int vMMVersion=MAKEWORD(1,1); int res = WSAStartup(vMMVersion, &wsaData); SOCKET hSkt = socket(AF_INET,SOCK_STREAM,res); if (INVALID_SOCKET == hSkt){ OutputDebugString("WebRequest socket create failed!\n"); return false; } ACloseSkt askt(hSkt); //是否设置为异步 if ( pRP && pRP->bBlock == false) { ULONG nMode = 1; ioctlsocket( hSkt,FIONBIO,&nMode); } string strURL(szURL),host,ip,requrl; unsigned int nport = 80; if ( stricmp(string(strURL.substr(0,7)).c_str(), "http://") ) { OutputDebugString("WebRequest parse url error, need http://\n"); return false; }else{ //parse url; size_t nMH = strURL.find(‘:‘,8); size_t nPre =strURL.find(‘/‘,8); if ( nMH == -1 && nPre == -1) { host = strURL.substr(7); requrl = "/"; }else if ( nPre != -1){ if ( nMH != -1 && nPre > nMH){ host = strURL.substr(7,nMH-7); nport = atoi( string(strURL.substr(nMH+1, nPre-1-nMH)).c_str()); }else{ host = strURL.substr(7,nPre-7); } requrl = strURL.substr(nPre); }else if (nMH != -1){ host = strURL.substr(7, nMH-7); nport= atoi( string(strURL.substr(nMH+1)).c_str()); requrl = "/"; } } GetRealIP(host,ip); sockaddr_in addr; addr.sin_addr.S_un.S_addr = inet_addr( ip.c_str() ); addr.sin_port = htons(nport); addr.sin_family = AF_INET; if (pRP && pRP->bBlock) { if (SOCKET_ERROR == connect( hSkt, (sockaddr*)&addr,sizeof(addr))) { OutputDebugString("WebRequest connect server failed!\n"); return false; } }else{ if (SOCKET_ERROR == connect( hSkt, (sockaddr*)&addr, sizeof(addr))) { if ( WSAGetLastError() == 10035 ) { //connectioning }else{ OutputDebugString("WebRequest connect server failed!\n"); return false; } } DWORD dwTick = GetTickCount(); do{ fd_set Set,WSet; FD_ZERO(&Set); FD_ZERO(&WSet); FD_SET(hSkt,&Set); FD_SET(hSkt,&WSet); timeval time; time.tv_sec = 0; time.tv_usec = 0; int nS = select(0, &Set, &WSet, NULL, &time); if( nS == SOCKET_ERROR ) { OutputDebugString("WebRequest connect server failed!(SELECT)\n"); return false; }else if(nS){ break;//connect sucess. }else{ if ( (GetTickCount() - dwTick) > pRP->uiTimeout ) { //timeout OutputDebugString("WebRequest connect server timeout!(SELECT)\n"); return false; } } }while(true); } //fill header; string header; bool bSendBin = false; if (pRP) { header.append( pRP->bPost ? "POST " : "GET "); header.append(requrl); header.append(" HTTP/1.1\r\n"); header.append("host:"); header.append(host); header.append("\r\nUser-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n"); header.append("Content-Type:application/x-www-form-urlencoded\r\n"); header.append("Accept:text/html,application/xhtml+xml,*/*\r\nConnection:close\r\n"); char szCSize[50]; sprintf(szCSize,"Content-Length:%d\r\n\r\n",pRP->uiPostLen); header.append(szCSize); if (pRP->pPostData){ if ( strlen(pRP->pPostData) <= pRP->uiPostLen){ bSendBin = true; }else{ header.append(pRP->pPostData); } } }else{ header.append("GET "); header.append(requrl); header.append(" HTTP/1.1\r\n"); header.append("host:"); header.append(host); header.append("\r\nUser-Agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n"); header.append("Content-Type:application/x-www-form-urlencoded\r\n"); header.append("Accept:text/html,application/xhtml+xml,*/*\r\nConnection:close\r\n\r\n"); } size_t headerlen = header.size(); size_t nSendLen = 0; const char* pdata = header.c_str(); DWORD dwTick = GetTickCount(); do { int n = send(hSkt, pdata + nSendLen, int(headerlen - nSendLen),0); if( n == SOCKET_ERROR ){ if ( 10035 == WSAGetLastError()) { //wait for send. if (pRP && GetTickCount() - dwTick >= pRP->uiTimeout) { OutputDebugString("WebRequest send failed!\n"); return false; } Sleep(10); }else{ OutputDebugString("WebRequest send failed!\n"); return false; } }else if( n==0) { OutputDebugString("WebRequest send failed!\n"); return false; break; }else{ dwTick = GetTickCount(); nSendLen += n; } } while (nSendLen < headerlen ); if(bSendBin && pRP && pRP->pPostData && pRP->uiPostLen) { nSendLen = 0; pdata = (const char*) pRP->pPostData; dwTick = GetTickCount(); do { int n = send(hSkt, pdata + nSendLen, pRP->uiPostLen - nSendLen,0); if( n == SOCKET_ERROR ){ if ( 10035 == WSAGetLastError()) { //wait for send. if (pRP && GetTickCount() - dwTick >= pRP->uiTimeout) { OutputDebugString("WebRequest send timeout!\n"); return false; } Sleep(10); }else{ OutputDebugString("WebRequest send failed!\n"); return false; } }else if( n==0) { OutputDebugString("WebRequest send failed!\n"); return false; break; }else{ dwTick = GetTickCount(); nSendLen += n; } } while (nSendLen < pRP->uiPostLen ); } //recv response char buf[2049]; string& request = response; request.clear(); dwTick = GetTickCount(); do { int n = recv(hSkt, buf,2048,0); if ( n == SOCKET_ERROR ) { if ( 10035 != WSAGetLastError() ) { OutputDebugString("DevWebService recv failed!\n"); return 0; break; }else{ if (pRP && GetTickCount() - dwTick >= pRP->uiTimeout){ OutputDebugString("WebRequest recv timeout!\n"); return false; } Sleep(10); } }else if( n == 0 ){ //host close recv finish OutputDebugString("WebRequest Recv FINISHED!\n"); break; }else{ buf[n] = ‘\0‘; request.append(buf); dwTick = GetTickCount(); } } while (true); return true; } string GetHtml(string response) { int conn_index=response.find("Connection:"); string str=response.substr(conn_index); int line_index=str.find("\r\n"); if(line_index!=-1) { string contect=str.substr(line_index); //MessageBox(NULL,contect.c_str(),"ok",0); return contect; } return str; } } //UTF8编码 std::string utf2ansi(LPCSTR pszSrc) { int nSize = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pszSrc, -1, 0, 0); if(nSize <= 0) return NULL; WCHAR *pwsz = new WCHAR[nSize+1]; if( NULL == pwsz) return NULL; MultiByteToWideChar(CP_UTF8, 0,(LPCSTR)pszSrc, nSize, pwsz, nSize); pwsz[nSize] = 0; char *psz = new char[nSize+1]; WideCharToMultiByte(CP_ACP, 0, pwsz, nSize, psz, nSize, NULL, NULL); string str = psz; delete pwsz; delete psz; return str; } int WideToUTF8(const std::string& _src,string fileName) { int nBufSize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)_src.c_str(),-1, NULL, 0, 0, FALSE); char *szBuf = new char[nBufSize]; WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)_src.c_str(),-1, szBuf, nBufSize, 0, FALSE); ofstream fout(fileName.c_str(),std::ios::out);//std::ios::binary fout.write(szBuf,nBufSize); fout.close(); //std::string strRet(szBuf); //delete []szBuf; //szBuf = NULL; /** 写出宽字符串时这样用,内容在text中 if(fopen_s( &pFile, "log.txt","a")!=0) { std::string str = WideToUTF8( text ); fputs(str.c_str(), pFile); fputc(‘\n‘,pFile); fclose(pFile); }*/ return 0; } int writeToTxt(string fileName,string data) { ofstream fout(fileName.c_str(),std::ios::out);//std::ios::binary //0xef, 0xbb, 0xbf, //fout.write((char*)0x00ef,4); //fout.write((char*)0x00bb,4); //fout.write((char*)0x00bf,4); //unsigned char uniTxt[] = {0xFF, 0xFE}; // Unicode file header //unsigned char endianTxt[] = {0xFE, 0xFF}; // Unicode big endian file header //unsigned char utf8Txt[] = {0xEF, 0xBB, 0xBF}; // UTF_8 file header fout<<0xEF<<0xBB<<0xBF<<endl; fout.write(data.c_str(),data.length()); fout.close(); return 0; } int writeToTxt002(string fileName,string data) { FILE *file; file=fopen(fileName.c_str(),"rw"); if(file==NULL) { printf("打开失败!\n"); return -1; } fwrite(data.c_str(),data.length(),1,file); fclose(file); return 0; } int _tmain(int argc, _TCHAR* argv[]) { string rs; char post[80]; sprintf(post,"username=xj&userpassword=123456"); DEVWEB::RequestParam rp; rp.bPost = false; rp.pPostData = post; rp.uiPostLen = strlen(post); if ( DEVWEB::WebRequest( "http://www.baidu.com", rs,&rp)) { rs=utf2ansi(rs.c_str()); MessageBox(NULL,rs.c_str(),"ok",0); string html=DEVWEB::GetHtml(rs); MessageBox(NULL,html.c_str(),"ok",0); writeToTxt("test.html",html); }else{ MessageBox(NULL,"错误","ok",0); } getchar(); return 0; }
时间: 2024-10-07 11:00:16