SOCKET通过代理连接服务器

[cpp]  view plain copy print ?
  1. 代理方式包括:HTTP代理、SOCKET5代理。RFC参考文档:http://oss.org.cn/man/develop/rfc/default.htm  
  2. 一、通过HTTP代理  
  3.   
  4. int CProxy_TestDlg::HttpConnect(const char *proxy_ip,int proxy_port,const char *svr_ip,int svr_port)  
  5. {  
  6.     SOCKET socket_ = ::socket(AF_INET,SOCK_STREAM,0);  
  7.     sockaddr_in sa;  
  8.     sa.sin_addr.s_addr = inet_addr(proxy_ip);  
  9.     sa.sin_port = htons(proxy_port);  
  10.     sa.sin_family = AF_INET;  
  11.   
  12.     int error_code = ::connect(socket_,(SOCKADDR*)&sa,sizeof(sa));    
  13.     if(error_code == SOCKET_ERROR)    
  14.     {    
  15.         ::closesocket(socket_);  
  16.         return 1;    
  17.     }    
  18.     char tmpBuffer[128] = {0};  
  19.     ::sprintf(tmpBuffer,"CONNECT %s:%d HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\nConnection: Keep-Alive\r\n\r\n",svr_ip,svr_port);  
  20.     ::send(socket_,tmpBuffer,strlen(tmpBuffer),0);    
  21.     memset(tmpBuffer,0,128);  
  22.     ::recv(socket_,tmpBuffer,128,0);   
  23.     int mj, mi, code;  
  24.     ::sscanf(tmpBuffer, "HTTP/%d.%d %d", &mj, &mi, &code);  
  25.     if (code != 200)  
  26.     {   
  27.         ::closesocket(socket_);  
  28.         return 2;  
  29.     }  
  30.     ::closesocket(socket_);  
  31.     return 0;  
  32. }  
  33.   
  34. HTTP代理方式测试通过。。。  
  35. 二、SOCKET5代理  
  36. 1、使用的结构如下:  
  37.   
  38. #pragma pack(push,1)  
  39. //请求认证方式  
  40. typedef struct tagSocket5_Requst  
  41. {  
  42.     char Ver;            //版本号:05  
  43.     char NMethods;  
  44.     char Methods[255];  
  45. }Socket5_Request,*LPSocket5_Request;  
  46. //认证方式应答  
  47. typedef struct tagSocket5_Response  
  48. {  
  49.     char Ver;  
  50.     char Method;//X'00'不需要认证;X'01'GSSAPI;X'02用户名/密码;X'03' -- X'7F'由IANA分配;X'80' -- X'FE'为私人方法所保留的;X'FF'没有可以接受的方法  
  51.   
  52. }Socket5_Response,*LPSocket5_Response;  
  53.   
  54. //认证请求  
  55. typedef struct tagSocket5_Auth_Request  
  56. {  
  57.     char   Ver;   //1   
  58.     char   Ulen;      
  59.     char   Name[255];      
  60.     char   PLen;      
  61.     char   Pass[255];  
  62. }Socket5_Auth_Request,*LPSocket5_Auth_Request;  
  63.   
  64. typedef struct tagSocket5_Auth_Response  
  65. {    
  66.     char   Ver;      
  67.     char   Status;   
  68. }Socket5_Auth_Response,*LPSocket5_Auth_Response;  
  69. //连接请求  
  70. typedef struct tagSocket5_Connect_Request  
  71. {  
  72.     char Ver;  
  73.     char Cmd;//CONNECT:X'01';BIND:X'02';UDP ASSOCIATE:X'03'  
  74.     char Rsv;//保留,填0  
  75.     char Atyp;//   后面的地址类型,IPV4:X'01';域名:X'03';IPV6:X'04',暂时只支持IPV4  
  76.     unsigned long DestAddr;//IPV4是4个字节,IPV6是6个字节;基于域名的地址,地址字段中的第一字节是以字节为单位的该域名的长度,没有结尾的NUL字  
  77.     unsigned short DestPort;  
  78.   
  79. }Sokcet5_Connect_Request,*LPSocket5_Connect_Request;  
  80. //连接应答  
  81. typedef struct tagSokcet5_Connect_Response  
  82. {  
  83.     char Ver;  
  84.     char Rep;  
  85.     char Rsv;  
  86.     char Atyp;  
  87.     unsigned long DestAddr;  
  88.     unsigned short DestPort;  
  89. }Socket5_Connect_Response,*LPSocket5_Connect_Response;  
  90. #pragma pack(pop)  
  91. 2、函数定义:  
  92. int CProxy_TestDlg::Socket5Connect(const char *proxy_ip,int proxy_port,const char *user,const char *passwd,const char *svr_ip,int svr_port)  
  93. {  
  94.     //首先连接SOCKET5代理服务器  
  95.     SOCKET socket_ = ::socket(AF_INET,SOCK_STREAM,0);  
  96.     sockaddr_in sa;  
  97.     sa.sin_addr.s_addr = inet_addr(proxy_ip);  
  98.     sa.sin_port = htons(proxy_port);  
  99.     sa.sin_family = AF_INET;  
  100.   
  101.     int error_code = ::connect(socket_,(SOCKADDR*)&sa,sizeof(sa));    
  102.     if(error_code == SOCKET_ERROR)    
  103.     {    
  104.         ::closesocket(socket_);  
  105.         return 1;    
  106.     }    
  107.     char buffer[128] = {0};  
  108.     int len = 0;  
  109.     //发送认证发送请求Socket5_Request/Socket5_Response  
  110.     Socket5_Request req;  
  111.     Socket5_Response rep;  
  112.     req.Ver = 0x05;  
  113.     req.NMethods = 2;  
  114.     req.Methods[0] = 0;  
  115.     req.Methods[1] = 2;  
  116.     if((len = ::send(socket_,(char*)&req,sizeof(req),0)) <=0)  
  117.     {  
  118.         ::closesocket(socket_);  
  119.         return 4;  
  120.     }  
  121.   
  122.     if((len = ::recv(socket_,(char*)&rep,sizeof(rep),0)) <=0)  
  123.     {  
  124.         ::closesocket(socket_);  
  125.         return 4;  
  126.     }  
  127.   
  128.     if(rep.Ver != 0x05)  
  129.     {  
  130.         ::closesocket(socket_);  
  131.         return 5;  
  132.     }  
  133.   
  134.     if(rep.Method != 0x00 && rep.Method != 0x02)  
  135.     {  
  136.         ::closesocket(socket_);  
  137.         return 6;  
  138.     }  
  139.   
  140.     if(rep.Method == 0x02)  
  141.     {//需要用户名、密码验证  
  142.       
  143.         //进行认证Socket5_Auth_Request/Socket5_Auth_Response  
  144.         Socket5_Auth_Request auth_req;  
  145.         Socket5_Auth_Response auth_rep;  
  146.         memset(&auth_req,0,sizeof(Socket5_Auth_Request));  
  147.         memset(&auth_rep,0,sizeof(Socket5_Auth_Response));  
  148.         auth_req.Ver = 1;//?  
  149.         auth_req.Ulen = strlen(user);  
  150.         strcpy(auth_req.Name,user);  
  151.         auth_req.PLen = strlen(passwd);  
  152.         strcpy(auth_req.Pass,passwd);  
  153.         if((len = ::send(socket_,(char*)&auth_req,sizeof(auth_req),0)) <=0)  
  154.         {  
  155.             ::closesocket(socket_);  
  156.             return 4;  
  157.         }  
  158.         if((len = ::recv(socket_,(char*)&auth_rep,sizeof(auth_rep),0)) <=0)  
  159.         {  
  160.             ::closesocket(socket_);  
  161.             return 4;  
  162.         }  
  163.         if(auth_rep.Status != 0)  
  164.         {  
  165.             ::closesocket(socket_);  
  166.             return 7;  
  167.         }  
  168.     }  
  169.     //发送连接请求Sokcet5_Connect_Request/Socket5_Connect_Response  
  170.     Sokcet5_Connect_Request conn_req;  
  171.     Socket5_Connect_Response conn_rep;  
  172.     memset(&conn_req,0,sizeof(Sokcet5_Connect_Request));  
  173.     memset(&conn_rep,0,sizeof(Socket5_Connect_Response));  
  174.   
  175.     conn_req.Ver = 0x05;  
  176.     conn_req.Cmd = 0x01;//  
  177.     conn_req.Atyp = 0x01;  
  178.     conn_req.DestAddr = inet_addr(svr_ip);  
  179.     conn_req.DestPort = htons(svr_port);  
  180.   
  181.     if((len = ::send(socket_,(char*)&conn_req,sizeof(conn_req),0)) <=0)  
  182.     {  
  183.         ::closesocket(socket_);  
  184.         return 4;  
  185.     }  
  186.   
  187.     if((len = ::recv(socket_,(char*)&conn_rep,sizeof(conn_rep),0)) <=0)  
  188.     {  
  189.         ::closesocket(socket_);  
  190.         return 4;  
  191.     }  
  192.     if(conn_rep.Rep != 0)  
  193.     {  
  194.         ::closesocket(socket_);  
  195.         return 8;  
  196.     }  
  197.     //连接成功  
  198.   
  199.     ::closesocket(socket_);  
  200.     return 0;  
  201. }  
  202.   
  203. SOCKET5还没有测试。。。  
  204. 三、根据网址获取该网址的IP地址  
  205. char * URL2IP(const char *url)  
  206. {  
  207.     struct hostent * ph;  
  208.     struct in_addr in;  
  209.     memset( &in, 0x0, sizeof(in) );  
  210.     // 传递的域名地址通过 gethostbyname 函数转换成 HOSTENT 结构的指针  
  211.     if((ph = gethostbyname(url)) == NULL)  
  212.         return NULL;  
  213.   
  214.     memcpy( (char**)&in, ph->h_addr_list[0], sizeof(in) );  
  215.   
  216.     return ::inet_ntoa( in );   

  1. }  
转载自:http://blog.csdn.net/educast/article/details/17450951

你可能感兴趣的:(linux)