Win32 - Google浏览器
//////////////////////////////////////////////////////////////////// // // ping百度 拿到一个IP 浏览器发送一个get请求 // 百度的服务器接收到了请求 返回一些东西给你 // 返回的东西就是我们想要的 // //////////////////////////////////////////////////////////////////// #include "stdafx.h" #include <iostream> #include <fstream> #include <winsock2.h> #include <string> #pragma comment(lib,"ws2_32.lib") using namespace std; /** * 解析URL * @param strUrl 待解析的域名 * @param strHost OUT 主机名 * @param strResource OUT * @return false 解析失败 */ BOOL ParseUrl(const string strUrl, string &strHost, string &strResource) { BOOL bRet = FALSE; const int MAXRESOURCESIZE = 2000; const int MINHOSTSIZE = 5; do { string strHttp = "http://"; // 从strUrl中找到"http://" const char * szPos = strstr(strUrl.c_str(), strHttp.c_str()); // 如果没有找到首"http://",说明没有http if (NULL == szPos) { szPos = strUrl.c_str(); } else { szPos = szPos + strHttp.length(); } char szHost[MAXBYTE] = { 0 }; char szResource[MAXRESOURCESIZE] = { 0 }; // 标准写法:长度2000(MAXRESOURCESIZE = 2000) sscanf_s(szPos, "%[^/]%s", szHost, MAXBYTE, szResource, MAXBYTE); if (MINHOSTSIZE > strlen(szHost)) { break; } strHost = szHost; // 如果不等于0,说明szResource不为空 if (0 != strlen(szResource)) { strResource = szResource; bRet = TRUE; } else { strResource = "/"; } } while (FALSE); return bRet; } int _tmain(int argc, _TCHAR* argv[]) { BOOL bRet = FALSE; SOCKET socketServer = INVALID_SOCKET; char *pszBuffer = NULL; do { WSADATA wsaData; // 初始化socket if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { break; } if (2 != LOBYTE(wsaData.wVersion) || 2 != HIBYTE(wsaData.wVersion)) { break; } // 服务端: 通过编程, 将域名转换成IP string strUrl = "www.wmpic.me/meinv"; string strHost, strResouce; ParseUrl(strUrl, strHost, strResouce); printf("Host:%s \t Rosouce:%s \r\n", strHost.c_str(), strResouce.c_str()); //获取主机 HOSTENT * hServerHost = gethostbyname(strHost.c_str()); if (NULL == hServerHost) { WSACleanup(); break; } sockaddr_in addrServer = { 0 }; addrServer.sin_family = AF_INET; addrServer.sin_port = htons(80); // 80端口 memcpy(&(addrServer.sin_addr), hServerHost->h_addr, 4); // 创建socket socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == socketServer) { closesocket(socketServer); WSACleanup(); break; } // 连接socket if (SOCKET_ERROR == connect(socketServer, (SOCKADDR*)&addrServer, sizeof(addrServer))) { closesocket(socketServer); WSACleanup(); break; } // 发送Get请求: "GET "后面有一个空格, " HTTP/1.1" HTTP前面有个空格 // 右值为截取封包获取的 string strRequest = "GET " + strResouce + " HTTP/1.1\r\nHost:" + strHost + "\r\nConnection:Close\r\n\r\n"; if (SOCKET_ERROR == send(socketServer, strRequest.c_str(), strRequest.length(), 0)) { closesocket(socketServer); WSACleanup(); break; } // 返回的数据不可能一次性接收完毕,所以必须要用循环读取,直到recv返回0,接收完毕! const int MAXBUFFERSIZE = 1 * 1024 * 1024; pszBuffer = (char *)malloc(MAXBUFFERSIZE); ZeroMemory(pszBuffer, MAXBUFFERSIZE); int iRecvSize = 1; int iOffset = 0; int iReallocCount = 2; while (0<iRecvSize) { iRecvSize = recv(socketServer, pszBuffer + iOffset, 100000 - iOffset, 0); iOffset += iRecvSize; if (MAXBUFFERSIZE - iOffset < 100) { pszBuffer = (char*)realloc(pszBuffer, MAXBUFFERSIZE * 2); iReallocCount++; } } cout << "szBuffer = " << pszBuffer << endl; // 创建一个文件接收szBuffer ofstream outPUtstream("Buffer.txt", ios::app); outPUtstream << pszBuffer; outPUtstream.close(); // 清理socket if (INVALID_SOCKET != socketServer) { closesocket(socketServer); WSACleanup(); } } while (FALSE); if (pszBuffer) { free(pszBuffer); pszBuffer = NULL; } getchar(); return 0; }