24小时热门版块排行榜    

查看: 278  |  回复: 0
当前主题已经存档。

zsglly

木虫 (著名写手)

[交流] 总结一些TCP协议穿透代理服务器的程序片断

在网络程序设计过程中,我们经常要与各种类型的代理服务器打交道,比如在企业内部网通过代理去访问Internet网上的服务器等等,一般代理服务器支持几种常见的代理协议标准,如Socks4,Socks5,Http代理,其中Socks5需要用户验证,代理相对复杂。我在查阅RFC文档和相关资料后,特总结一些TCP协议穿透代理服务器的程序片断,希望对大家有所帮助。  

//使用到的结构  
struct sock4req1  
{  
char VN;  
char CD;  
unsigned short Port;  
unsigned long IPAddr;  
char other[1];  
};  

struct sock4ans1  
{  
char VN;  
char CD;  
};  

struct sock5req1  
{  
char Ver;  
char nMethods;  
char Methods[255];  
};  

struct sock5ans1  
{  
char Ver;  
char Method;  
};  

struct sock5req2  
{  
char Ver;  
char Cmd;  
char Rsv;  
char Atyp;  
char other[1];  
};  

struct sock5ans2  
{  
char Ver;  
char Rep;  
char Rsv;  
char Atyp;  
char other[1];  
};  

struct authreq  
{  
char Ver;  
char Ulen;  
char Name[255];  
char PLen;  
char Pass[255];  
};  

struct authans  
{  
char Ver;  
char Status;  
};  

//通过Socks4方式代理  
if( !ClientSock.Connect( g_ProxyInfo.m_strProxyIP,g_ProxyInfo.m_nProxyPort) )  
{  
m_sError = _T("不能连接到代理服务器!";  
ClientSock.Close();  
return FALSE;  
}  
char buff[100];  
memset(buff,0,100);  
struct sock4req1 *m_proxyreq;  
m_proxyreq = (struct sock4req1 *)buff;  
m_proxyreq->VN = 4;  
m_proxyreq->CD = 1;  
m_proxyreq->Port = ntohs(GetPort());  
m_proxyreq->IPAddr = inet_addr(GetServerHostName());  
ClientSock.Send(buff,9);  
struct sock4ans1 *m_proxyans;  
m_proxyans = (struct sock4ans1 *)buff;  
memset(buff,0,100);  
ClientSock.Receive(buff,100);  
if(m_proxyans->VN != 0 || m_proxyans->CD != 90)  
{  
m_sError = _T("通过代理连接主站不成功!";  
ClientSock.Close();  
return FALSE;  
}  




//通过Socks5方式代理  
if( !ClientSock.Connect( g_ProxyInfo.m_strProxyIP,g_ProxyInfo.m_nProxyPort) )  
{  
m_sError = _T("不能连接到代理服务器!";  
ClientSock.Close();  
return FALSE;  
}  
char buff[600];  
struct sock5req1 *m_proxyreq1;  
m_proxyreq1 = (struct sock5req1 *)buff;  
m_proxyreq1->Ver = 5;  
m_proxyreq1->nMethods = 2;  
m_proxyreq1->Methods[0] = 0;  
m_proxyreq1->Methods[1] = 2;  
ClientSock.Send(buff,4);  
struct sock5ans1 *m_proxyans1;  
m_proxyans1 = (struct sock5ans1 *)buff;  
memset(buff,0,600);  
ClientSock.Receive(buff,600);  
if(m_proxyans1->Ver != 5 || (m_proxyans1->Method!=0 && m_proxyans1->Method!=2))  
{  
m_sError = _T("通过代理连接主站不成功!";  
ClientSock.Close();  
return FALSE;  
}  
if(m_proxyans1->Method == 2)  
{  
int nUserLen = strlen(g_ProxyInfo.m_strProxyUser);  
int nPassLen = strlen(g_ProxyInfo.m_strProxyPass);  
struct authreq *m_authreq;  
m_authreq = (struct authreq *)buff;  
m_authreq->Ver = 1;  
m_authreq->Ulen = nUserLen;  
strcpy(m_authreq->Name,g_ProxyInfo.m_strProxyUser);  
m_authreq->PLen = nPassLen;  
strcpy(m_authreq->Pass,g_ProxyInfo.m_strProxyPass);  
ClientSock.Send(buff,513);  
struct authans *m_authans;  
m_authans = (struct authans *)buff;  
memset(buff,0,600);  
ClientSock.Receive(buff,600);  
if(m_authans->Ver != 1 || m_authans->Status != 0)  
{  
m_sError = _T("代理服务器用户验证不成功!";  
ClientSock.Close();  
return FALSE;  
}  
}  
struct sock5req2 *m_proxyreq2;  
m_proxyreq2 = (struct sock5req2 *)buff;  
m_proxyreq2->Ver = 5;  
m_proxyreq2->Cmd = 1;  
m_proxyreq2->Rsv = 0;  
m_proxyreq2->Atyp = 1;  
unsigned long tmpLong = inet_addr(GetServerHostName());  
unsigned short port = ntohs(GetPort());  
memcpy(m_proxyreq2->other,&tmpLong,4);  
memcpy(m_proxyreq2->other+4,&port,2);  
ClientSock.Send(buff,sizeof(struct sock5req2)+5);  
struct sock5ans2 *m_proxyans2;  
memset(buff,0,600);  
m_proxyans2 = (struct sock5ans2 *)buff;  
ClientSock.Receive(buff,600);  
if(m_proxyans2->Ver != 5 || m_proxyans2->Rep != 0)  
{  
m_sError = _T("通过代理连接主站不成功!";  
ClientSock.Close();  
return FALSE;  
}  




//通过HTTP方式代理  
if( !ClientSock.Connect( g_ProxyInfo.m_strProxyIP,g_ProxyInfo.m_nProxyPort) )  
{  
m_sError = _T("不能连接到代理服务器!";  
ClientSock.Close();  
return FALSE;  
}  
char buff[600];  
sprintf( buff, "%s%s:%d%s","CONNECT ",GetServerHostName(),GetPort()," HTTP/1.1\r\nUser-Agent: MyApp/0.1\r\n\r\n";  
ClientSock.Send(buff,strlen(buff)); //发送请求  
memset(buff,0,600);  
ClientSock.Receive(buff,600);  
if(strstr(buff, "HTTP/1.0 200 Connection established" == NULL) //连接不成功  
{  
m_sError = _T("通过代理连接主站不成功!";  
ClientSock.Close();  
return FALSE;  
}  
我们一般先与代理服务器连通,然后向代理服务器发送代理验证的用户名和密码(如果需要,如Socks5代理),验证成功后,再向代理服务器发送需要连接的目的地址和端口。以上代码仅用于TCP连接,如果在内部网侦听或通过UDP协议发送信息,可查阅RFC1829等文档资料

[ Last edited by 幻影无痕 on 2006-11-17 at 08:25 ]
回复此楼
做人要厚道啊!厚道啊!
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 zsglly 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[硕博家园] 售SCI文章,我:8O.5.5.1O.54,科目全,可十急 +3 63GmZBFV29mG 2026-08-29 5/250 2026-08-31 03:42 by hZiFeudZyoGR
[公派出国] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +4 jCd0dEvKHShX 2026-08-29 6/300 2026-08-31 02:54 by hZiFeudZyoGR
[博后之家] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +3 G6APbkg8SA6w 2026-08-29 5/250 2026-08-31 01:51 by hZiFeudZyoGR
[考研] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +3 G6APbkg8SA6w 2026-08-29 6/300 2026-08-31 01:48 by hZiFeudZyoGR
[博后之家] 售SCI文章,我:8O.5.5.1O.54,科目全,可十急 +6 gy1nBQXYQJqL 2026-08-29 9/450 2026-08-31 01:05 by hZiFeudZyoGR
[考研] 售一区SCI文章T0P,我:8O.551.O54,科目全,可十急 +7 ASdOkHsho7FD 2026-08-28 11/550 2026-08-31 00:32 by hZiFeudZyoGR
[基金申请] 能否申诉? +4 echo8914667 2026-08-30 5/250 2026-08-30 21:11 by echo8914667
[考博] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +4 G6APbkg8SA6w 2026-08-29 5/250 2026-08-30 18:50 by hZiFeudZyoGR
[硕博家园] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +4 G6APbkg8SA6w 2026-08-29 5/250 2026-08-30 18:40 by hZiFeudZyoGR
[考研] 售SCI一区文章,我:8.O.551.O.5.4,科目全,可伽急 +4 gy1nBQXYQJqL 2026-08-29 6/300 2026-08-30 17:47 by hZiFeudZyoGR
[找工作] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +6 ASdOkHsho7FD 2026-08-28 10/500 2026-08-30 17:36 by hZiFeudZyoGR
[考研] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +8 ASdOkHsho7FD 2026-08-28 12/600 2026-08-30 17:11 by hZiFeudZyoGR
[考博] 找导师 +6 yuanjiabao 2026-08-29 7/350 2026-08-30 14:40 by 生科新手
[教师之家] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +5 ASdOkHsho7FD 2026-08-28 7/350 2026-08-30 06:10 by ZPa0EcMwuECS
[基金申请] 为什么资助数各大高校都创新高,自己申请怎么就这么难 +12 Kittylucky 2026-08-27 13/650 2026-08-29 00:04 by superceng
[基金申请] 面上合作单位盖章 +5 ssyjh 2026-08-27 5/250 2026-08-27 20:50 by gdfollow
[基金申请] 国际合作可查了,中了面上 (EPI+1)(金币+50) +18 Ldrop2023 2026-08-26 18/900 2026-08-26 11:15 by cmrandy
[基金申请] 系统进不去 +4 yanglien 2026-08-26 5/250 2026-08-26 11:10 by wenfengw83
[基金申请] 今天务委会开完了,明天出结果吗 +19 angus9576 2026-08-25 23/1150 2026-08-26 10:03 by zp519
[基金申请] 牛来!米来!面来! +8 beefly 2026-08-26 8/400 2026-08-26 08:37 by xuzhipiao
信息提示
请填处理意见