zoukankan      html  css  js  c++  java
  • C++ 请求http代理

    一开始使用winhttp....但是!实在是找不到资料 也不知道要怎么设置,感觉哪个文档都有点看不懂

    最后采用socket设置代理

    网上搜了一圈各种都有 就是不能用!

    最后看到两个不错的博主 

    决定参考着自己写 !

    要使用的时候记得改下代理IP端口账密~

    参考了这两个作者的:

    https://blog.csdn.net/bodybo/article/details/7274865

    https://blog.csdn.net/yu1121jm/article/details/85132224

    我的代码记得改下账密哦  我等下再改个完善版本的出来

    #include <cstdio>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #include <Winsock2.h>
    #include <Ws2tcpip.h> 
    #pragma comment(lib, "Ws2_32.lib")
    using namespace std;
    
    #define     USE_PROXY       1 //是否使用代理
    #define     PROXY_ADDR      "42.101.45.83" //代理IP
    #define     PROXY_PORT      22807 //代理端口
    
    //把username:password 转成 Base64  比如 D5565507:568FD2320185转化成RDU1NjU1MDc6NTY4RkQyMzIwMTg1
    string Encode(const unsigned char* Data, int DataByte)
    {
        //编码表
        const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        //返回值
        string strEncode;
        unsigned char Tmp[4] = { 0 };
        int LineLength = 0;
        for (int i = 0; i < (int)(DataByte / 3); i++)
        {
            Tmp[1] = *Data++;
            Tmp[2] = *Data++;
            Tmp[3] = *Data++;
            strEncode += EncodeTable[Tmp[1] >> 2];
            strEncode += EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F];
            strEncode += EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F];
            strEncode += EncodeTable[Tmp[3] & 0x3F];
            if (LineLength += 4, LineLength == 76) { strEncode += "
    "; LineLength = 0; }
        }
        //对剩余数据进行编码
        int Mod = DataByte % 3;
        if (Mod == 1)
        {
            Tmp[1] = *Data++;
            strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2];
            strEncode += EncodeTable[((Tmp[1] & 0x03) << 4)];
            strEncode += "==";
        }
        else if (Mod == 2)
        {
            Tmp[1] = *Data++;
            Tmp[2] = *Data++;
            strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2];
            strEncode += EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)];
            strEncode += EncodeTable[((Tmp[2] & 0x0F) << 2)];
            strEncode += "=";
        }
    
        return strEncode;
    }
    
    //把 Base64 转成 username:password 比如 RDU1NjU1MDc6NTY4RkQyMzIwMTg1转化成D5565507:568FD2320185
    string Decode(const char* Data, int DataByte, int& OutByte)
    {
        //解码表
        const char DecodeTable[] =
        {
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            62, // '+'
            0, 0, 0,
            63, // '/'
            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
            0, 0, 0, 0, 0, 0, 0,
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
            13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
            0, 0, 0, 0, 0, 0,
            26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
            39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
        };
        //返回值
        string strDecode;
        int nValue;
        int i = 0;
        while (i < DataByte)
        {
            if (*Data != '
    ' && *Data != '
    ')
            {
                nValue = DecodeTable[*Data++] << 18;
                nValue += DecodeTable[*Data++] << 12;
                strDecode += (nValue & 0x00FF0000) >> 16;
                OutByte++;
                if (*Data != '=')
                {
                    nValue += DecodeTable[*Data++] << 6;
                    strDecode += (nValue & 0x0000FF00) >> 8;
                    OutByte++;
                    if (*Data != '=')
                    {
                        nValue += DecodeTable[*Data++];
                        strDecode += nValue & 0x000000FF;
                        OutByte++;
                    }
                }
                i += 4;
            }
            else// 回车换行,跳过
            {
                Data++;
                i++;
            }
        }
        return strDecode;
    }
    
    #if USE_PROXY
    SOCKET _connect(const char* addr, unsigned short port)
    #else
    SOCKET _connect(struct in_addr* addr, unsigned short port)
    #endif
    {
        SOCKET sockfd = INVALID_SOCKET;
        struct sockaddr_in sin = { 0 };
        int ret = 0;
    
        sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (INVALID_SOCKET == sockfd)
        {
            printf("socket failed.
    ");
            return sockfd;
        }
    
        sin.sin_family = AF_INET;
        sin.sin_port = htons(port);
    #if USE_PROXY
        //sin.sin_addr.s_addr = inet_addr(addr);
        inet_pton(AF_INET, addr, &sin.sin_addr);
    #else
        sin.sin_addr = *addr;
    #endif
        ret = connect(sockfd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in));
        if (0 != ret)
        {
            printf("socket failed.
    ");
            closesocket(sockfd);
            sockfd = INVALID_SOCKET;
        }
    
        return sockfd;
    }
    
    void _close(SOCKET sockfd)
    {
        if (INVALID_SOCKET != sockfd)
        {
            closesocket(sockfd);
        }
    }
    
    int Receive(SOCKET socket, char* buf, int bufLen)
    {
        return recv(socket, buf, bufLen, 0);
    }
    
    bool Send(SOCKET socket, const char* buf, int len)
    {
        long ilen = len;
        int sendCnt = 0;
        int ret;
    
        while (sendCnt < ilen)
        {
            if ((ret = send(socket, buf + sendCnt, ilen - sendCnt, 0)) == SOCKET_ERROR)
            {
                return false;
            }
            else
            {
                sendCnt += ret;
            }
        }
        return true;
    }
    
    void connect_proxy(SOCKET sockfd)
    {
        // proxy user and password: dXNlcm5hbWU6cGFzc3dvcmQ= is "username:password" with base64 encode
        //const char* header = "CONNECT myip.ipip.net:80 HTTP/1.1
    Authorization: Basic RDU1NjU1MDc6NTY4RkQyMzIwMTg1
    
    Proxy-Authorization: Basic RDU1NjU1MDc6NTY4RkQyMzIwMTg1
    
    ";
        const unsigned char a[] = { "D5565507:568FD2320185" };
        string b = Encode(a, 21);
        char header[2048];
        sprintf_s(header, sizeof(header), "CONNECT myip.ipip.net:80 HTTP/1.1
    Authorization: Basic %s
    
    Proxy-Authorization: Basic %s
    
    ", b.c_str(), b.c_str());
    
        int offset = 0;
        char buf[2048] = { 0 }; 
    
        Send(sockfd, header, strlen(header));
        Receive(sockfd, buf, sizeof(buf));
        cout << buf << endl;
        if (strstr(buf, "HTTP/1.1 200 Connection established") != NULL)
        {
            printf("OK
    ");
            printf("%s",buf);
        }
    }
    
    void http_request()
    {
        SOCKET sockfd = INVALID_SOCKET;
        struct hostent* host = NULL;
        const char* header = "GET / HTTP/1.1
    Host: myip.ipip.net
    
    "; //我们要请求的网址的域名
        char buf[2048] = { 0 };
    #if USE_PROXY
        sockfd = _connect(PROXY_ADDR, PROXY_PORT);
        connect_proxy(sockfd);
    #else
        host = gethostbyname("myip.ipip.net");
        sockfd = _connect((struct in_addr*)host->h_addr_list[0], 80);
    #endif
    
    
        Send(sockfd, header, strlen(header));
        Receive(sockfd, buf, sizeof(buf));
        _close(sockfd);
        string info(buf);
        //编码转换 防止在控制台显示乱码
        char* pszBuffer = new char[info.length() + 1];
        wchar_t* pszWideBuffer = new wchar_t[(info.length() + 1) * 2];
        memset(pszWideBuffer, 0, (info.length() + 1) * 2);
        memset(pszBuffer, 0, info.length() + 1);
        MultiByteToWideChar(CP_UTF8, 0, info.c_str(), info.length(), pszWideBuffer, (info.length() + 1) * 2);//将unicode编码,转换为宽字节
        WideCharToMultiByte(CP_ACP, 0, pszWideBuffer, wcslen(pszWideBuffer), pszBuffer, info.length() + 1, NULL, NULL);//将宽字节,转换为控制台编码
        //cout << pszBuffer;
        info = pszBuffer;
        delete[] pszBuffer;
        delete[] pszWideBuffer;
        cout << info << endl;
    }
    
    int main()
    {
        WSADATA wsaData; ///这个结构被用来存储 被WSAStartup函数调用后返回的 Windows Sockets数据
        WSAStartup(MAKEWORD(2, 2), &wsaData);//初始化网络编程能够使用的函数或方法等....初始化后,就可以创建套接字了  搜索对应的Socket库 这是使用2.2的版本
        http_request(); //请求数据 
        WSACleanup();//终止Winsock 2 DLL (Ws2_32.dll) 的使用
        return 0;
    }

  • 相关阅读:
    每日总结
    每日总结
    Panda Global要点聚焦,中国应加快布局迎接区块链发展升温
    Panda Global热点关注,区块链在物流行业的应用
    Panda 交易所为你解读,区块链提速有望推动数字经济更广阔发展
    Panda 交易所视点观察,金融场景区块链应用进程已经不可逆转
    Panda 交易所焦点观察,区块链技术在各国政府管理中的运用
    Panda 交易所前沿解读,完善顶层设计 构筑区块链创新创业人才高地
    Panda 交易所热点关注,支持区块链技术发展 赋能数字经济
    区块链技术会给我们的生活带来哪些影响?Panda Global 带你一文看懂!
  • 原文地址:https://www.cnblogs.com/Galesaur-wcy/p/15030200.html
Copyright © 2011-2022 走看看