24小时热门版块排行榜    

查看: 283  |  回复: 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-T0P文章,我:8O.5.5.1.O.54,科目齐全,可+急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 07:24 by 9i7PCSZyMzot
[论文投稿] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 07:24 by 9i7PCSZyMzot
[博后之家] 售SCI一区T0P文章,我:8.O.55.1.O.5.4,科目全,可+急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 07:12 by 9i7PCSZyMzot
[公派出国] 售SCI一区T0P文章,我:8O.55.1.O.5.4,科目齐全,可+急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 07:06 by 9i7PCSZyMzot
[基金申请] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 07:01 by 9i7PCSZyMzot
[考博] 售SCI文章,我:8O.5.5.1O.54,科目全,可十急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 07:01 by 9i7PCSZyMzot
[论文投稿] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +3 E4V9bALS54sj 2026-09-19 4/200 2026-09-20 06:55 by 9i7PCSZyMzot
[考研] 售SCI一区文章,我:8O5.5.1.O5.4,科目全,可伽急 +3 4pRyVGCVerAA 2026-09-19 3/150 2026-09-20 00:15 by 9i7PCSZyMzot
[硕博家园] 售SCI-T0P文章,我:8O.5.5.1.O.54,科目齐全,可+急 +3 4pRyVGCVerAA 2026-09-19 3/150 2026-09-20 00:03 by 9i7PCSZyMzot
[找工作] 售SCI一区T0P文章,我:8.O55.1.O.54,科目全,可十急 +4 4pRyVGCVerAA 2026-09-19 4/200 2026-09-20 00:03 by 9i7PCSZyMzot
[考博] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +3 4pRyVGCVerAA 2026-09-19 4/200 2026-09-19 23:51 by 9i7PCSZyMzot
[基金申请] 售SCI一区T0P文章,我:8.O55.1.O.54,科目全,可十急 +3 4pRyVGCVerAA 2026-09-19 4/200 2026-09-19 23:39 by 9i7PCSZyMzot
[论文投稿] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +3 4pRyVGCVerAA 2026-09-19 4/200 2026-09-19 23:27 by 9i7PCSZyMzot
[考研] 售SCI一区T0P文章,我:8.O55.1.O.54,科目全,可十急 +3 4pRyVGCVerAA 2026-09-19 4/200 2026-09-19 23:27 by 9i7PCSZyMzot
[公派出国] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +3 4pRyVGCVerAA 2026-09-19 4/200 2026-09-19 23:03 by 9i7PCSZyMzot
[考博] 售SCI一区T0P文章,我:8.O.55.1.O.54,科目齐全,可+急 +3 4pRyVGCVerAA 2026-09-19 4/200 2026-09-19 23:03 by 9i7PCSZyMzot
[基金申请] 国社科系统bug了,是不是要放榜了? +7 kynobel 2026-09-16 9/450 2026-09-19 14:52 by 接好运婷
[考博] 申博发邮件 +8 Lmengk 2026-09-15 9/450 2026-09-19 09:27 by 中间体超市
[考博] 上海工程技术大学激光智能制造课题组|2027级博士研究生招生公告 +7 水士口 2026-09-16 8/400 2026-09-16 13:47 by kkklens
[考博] 上海工程技术大学激光智能制造课题组招收博士研究生 +8 两三岁ss 2026-09-14 8/400 2026-09-16 09:46 by 水士口
信息提示
请填处理意见