Win32

////////////////////////////////////////////////////////////////////
//
// 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 	 Rosouce:%s 
", 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
Host:" + strHost + "
Connection:Close

";
        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;
}
原文地址:https://www.cnblogs.com/DuanLaoYe/p/5765680.html