• SOCKET通过代理连接服务器


    代理方式包括:HTTP代理、SOCKET5代理。RFC参考文档:http://oss.org.cn/man/develop/rfc/default.htm
    一、通过HTTP代理
    
    int CProxy_TestDlg::HttpConnect(const char *proxy_ip,int proxy_port,const char *svr_ip,int svr_port)
    {
        SOCKET socket_ = ::socket(AF_INET,SOCK_STREAM,0);
        sockaddr_in sa;
        sa.sin_addr.s_addr = inet_addr(proxy_ip);
        sa.sin_port = htons(proxy_port);
        sa.sin_family = AF_INET;
    
        int error_code = ::connect(socket_,(SOCKADDR*)&sa,sizeof(sa));  
        if(error_code == SOCKET_ERROR)  
        {  
            ::closesocket(socket_);
            return 1;  
        }  
        char tmpBuffer[128] = {0};
        ::sprintf(tmpBuffer,"CONNECT %s:%d HTTP/1.1
    User-Agent: Mozilla/4.0
    Connection: Keep-Alive
    
    ",svr_ip,svr_port);
        ::send(socket_,tmpBuffer,strlen(tmpBuffer),0);  
        memset(tmpBuffer,0,128);
        ::recv(socket_,tmpBuffer,128,0); 
        int mj, mi, code;
        ::sscanf(tmpBuffer, "HTTP/%d.%d %d", &mj, &mi, &code);
        if (code != 200)
        { 
            ::closesocket(socket_);
            return 2;
        }
        ::closesocket(socket_);
        return 0;
    }
    
    HTTP代理方式测试通过。。。
    二、SOCKET5代理
    1、使用的结构如下:
    
    #pragma pack(push,1)
    //请求认证方式
    typedef struct tagSocket5_Requst
    {
        char Ver;            //版本号:05
        char NMethods;
        char Methods[255];
    }Socket5_Request,*LPSocket5_Request;
    //认证方式应答
    typedef struct tagSocket5_Response
    {
        char Ver;
        char Method;//X'00'不需要认证;X'01'GSSAPI;X'02用户名/密码;X'03' -- X'7F'由IANA分配;X'80' -- X'FE'为私人方法所保留的;X'FF'没有可以接受的方法
    
    }Socket5_Response,*LPSocket5_Response;
    
    //认证请求
    typedef struct tagSocket5_Auth_Request
    {
        char   Ver;   //1 
        char   Ulen;    
        char   Name[255];    
        char   PLen;    
        char   Pass[255];
    }Socket5_Auth_Request,*LPSocket5_Auth_Request;
    
    typedef struct tagSocket5_Auth_Response
    {  
        char   Ver;    
        char   Status; 
    }Socket5_Auth_Response,*LPSocket5_Auth_Response;
    //连接请求
    typedef struct tagSocket5_Connect_Request
    {
        char Ver;
        char Cmd;//CONNECT:X'01';BIND:X'02';UDP ASSOCIATE:X'03'
        char Rsv;//保留,填0
        char Atyp;//   后面的地址类型,IPV4:X'01';域名:X'03';IPV6:X'04',暂时只支持IPV4
        unsigned long DestAddr;//IPV4是4个字节,IPV6是6个字节;基于域名的地址,地址字段中的第一字节是以字节为单位的该域名的长度,没有结尾的NUL字
        unsigned short DestPort;
    
    }Sokcet5_Connect_Request,*LPSocket5_Connect_Request;
    //连接应答
    typedef struct tagSokcet5_Connect_Response
    {
        char Ver;
        char Rep;
        char Rsv;
        char Atyp;
        unsigned long DestAddr;
        unsigned short DestPort;
    }Socket5_Connect_Response,*LPSocket5_Connect_Response;
    #pragma pack(pop)
    2、函数定义:
    int CProxy_TestDlg::Socket5Connect(const char *proxy_ip,int proxy_port,const char *user,const char *passwd,const char *svr_ip,int svr_port)
    {
        //首先连接SOCKET5代理服务器
        SOCKET socket_ = ::socket(AF_INET,SOCK_STREAM,0);
        sockaddr_in sa;
        sa.sin_addr.s_addr = inet_addr(proxy_ip);
        sa.sin_port = htons(proxy_port);
        sa.sin_family = AF_INET;
    
        int error_code = ::connect(socket_,(SOCKADDR*)&sa,sizeof(sa));  
        if(error_code == SOCKET_ERROR)  
        {  
            ::closesocket(socket_);
            return 1;  
        }  
        char buffer[128] = {0};
        int len = 0;
        //发送认证发送请求Socket5_Request/Socket5_Response
        Socket5_Request req;
        Socket5_Response rep;
        req.Ver = 0x05;
        req.NMethods = 2;
        req.Methods[0] = 0;
        req.Methods[1] = 2;
        if((len = ::send(socket_,(char*)&req,sizeof(req),0)) <=0)
        {
            ::closesocket(socket_);
            return 4;
        }
    
        if((len = ::recv(socket_,(char*)&rep,sizeof(rep),0)) <=0)
        {
            ::closesocket(socket_);
            return 4;
        }
    
        if(rep.Ver != 0x05)
        {
            ::closesocket(socket_);
            return 5;
        }
    
        if(rep.Method != 0x00 && rep.Method != 0x02)
        {
            ::closesocket(socket_);
            return 6;
        }
    
        if(rep.Method == 0x02)
        {//需要用户名、密码验证
        
            //进行认证Socket5_Auth_Request/Socket5_Auth_Response
            Socket5_Auth_Request auth_req;
            Socket5_Auth_Response auth_rep;
            memset(&auth_req,0,sizeof(Socket5_Auth_Request));
            memset(&auth_rep,0,sizeof(Socket5_Auth_Response));
            auth_req.Ver = 1;//?
            auth_req.Ulen = strlen(user);
            strcpy(auth_req.Name,user);
            auth_req.PLen = strlen(passwd);
            strcpy(auth_req.Pass,passwd);
            if((len = ::send(socket_,(char*)&auth_req,sizeof(auth_req),0)) <=0)
            {
                ::closesocket(socket_);
                return 4;
            }
            if((len = ::recv(socket_,(char*)&auth_rep,sizeof(auth_rep),0)) <=0)
            {
                ::closesocket(socket_);
                return 4;
            }
            if(auth_rep.Status != 0)
            {
                ::closesocket(socket_);
                return 7;
            }
        }
        //发送连接请求Sokcet5_Connect_Request/Socket5_Connect_Response
        Sokcet5_Connect_Request conn_req;
        Socket5_Connect_Response conn_rep;
        memset(&conn_req,0,sizeof(Sokcet5_Connect_Request));
        memset(&conn_rep,0,sizeof(Socket5_Connect_Response));
    
        conn_req.Ver = 0x05;
        conn_req.Cmd = 0x01;//
        conn_req.Atyp = 0x01;
        conn_req.DestAddr = inet_addr(svr_ip);
        conn_req.DestPort = htons(svr_port);
    
        if((len = ::send(socket_,(char*)&conn_req,sizeof(conn_req),0)) <=0)
        {
            ::closesocket(socket_);
            return 4;
        }
    
        if((len = ::recv(socket_,(char*)&conn_rep,sizeof(conn_rep),0)) <=0)
        {
            ::closesocket(socket_);
            return 4;
        }
        if(conn_rep.Rep != 0)
        {
            ::closesocket(socket_);
            return 8;
        }
        //连接成功
    
        ::closesocket(socket_);
        return 0;
    }
    
    SOCKET5还没有测试。。。
    三、根据网址获取该网址的IP地址
    char * URL2IP(const char *url)
    {
        struct hostent * ph;
        struct in_addr in;
        memset( &in, 0x0, sizeof(in) );
        // 传递的域名地址通过 gethostbyname 函数转换成 HOSTENT 结构的指针
        if((ph = gethostbyname(url)) == NULL)
            return NULL;
    
        memcpy( (char**)&in, ph->h_addr_list[0], sizeof(in) );
    
        return ::inet_ntoa( in ); 
    }

  • 相关阅读:
    Android使用SharedPreferences
    Flex程序基本结构顺序结构程序设计
    FLEX程序设计函数
    FLEX程序设计XML(2)
    FLEX程序设计事件和事件机制鼠标事件
    FLEX字符串
    FLEX程序基本结构循环结构程序设计
    Enum 作为一个数据源绑定(收藏)
    FLEX程序设计数字处理
    flex程序设计面向对象基础
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318506.html
Copyright © 2020-2023  润新知