zoukankan      html  css  js  c++  java
  • http代理 超时设置.... C++ socket

    #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      "124.225.157.123" //代理IP
    #define     PROXY_PORT      15326 //代理端口
    
    //把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);
        int nNetTimeout = 3000;//3秒
        //发送时限
        setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&nNetTimeout, sizeof(int));
        //接收时限
        setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&nNetTimeout, sizeof(int));
    
        //设置非阻塞方式连接
        unsigned long ul = 1;
        int retSocket = ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul);
    
        if (INVALID_SOCKET == sockfd || retSocket == SOCKET_ERROR )
        {
            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));
        //select模型 即设置超时
        struct timeval timeout;
        fd_set r;
    
        FD_ZERO(&r);
        FD_SET(sockfd, &r);
        timeout.tv_sec = 3; //连接超时30秒
        timeout.tv_usec = 0;
        int retCon = select(0, 0, &r, 0, &timeout);
        if (retCon <= 0)
        {
            ::closesocket(sockfd);
            return sockfd;
        }
        ul = 0;
        retSocket = ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul);
    
        if (retSocket == SOCKET_ERROR)
        {
            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)
    {
        int ret;
        if ((ret = send(socket, buf, len, 0)) == SOCKET_ERROR)
            return false;
        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[] = { "95E949FA:052C5B365DB4" };
        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;
    }
  • 相关阅读:
    第6章 键盘_6.5 插入符号(不是光标)
    第6章 键盘_6.3-6.4 字符消息、键盘消息和字符集
    第6章 键盘_6.1-6.2 键盘基础与击键消息
    第5章 绘图基础_5.6 矩形、区域和剪裁
    第4章 进程(1)
    第3章 内核对象(2)
    第3章 内核对象(1)
    第2章 字符和字符串处理(2)
    第2章 字符和字符串处理(1)
    第1章 错误处理
  • 原文地址:https://www.cnblogs.com/Galesaur-wcy/p/15165937.html
Copyright © 2011-2022 走看看