24小时热门版块排行榜    

Znn3bq.jpeg
查看: 271  |  回复: 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 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[考研] 一志愿中科大材料与化工,353分还有调剂学校吗 +7 否极泰来2026 2026-04-15 9/450 2026-04-16 13:40 by liumingli7817
[考研] 材料相关专业344求调剂双非工科学校或课题组 +22 hualkop 2026-04-12 24/1200 2026-04-16 10:54 by Espannnnnol
[考研] 344求调剂 +8 丶风雪夜归人丶 2026-04-09 8/400 2026-04-16 10:49 by 圆心602
[考研] 290调剂生物0860 +38 哇哈哈,。 2026-04-11 44/2200 2026-04-16 09:52 by cuisz
[考研] 211本科材料化工求调剂 +19 YHLAH 2026-04-11 23/1150 2026-04-14 22:25 by fenglj492
[考研] 药学305求调剂 +10 玛卡巴卡boom 2026-04-10 10/500 2026-04-14 15:55 by zs92450
[考研] 2026硕士调剂_能动_河南农业大学 +4 河南农业大学-能 2026-04-12 4/200 2026-04-13 22:01 by bljnqdcc
[考研] 0831一轮调剂失败求助 +10 小熊睿睿_s 2026-04-11 10/500 2026-04-12 22:43 by 长弓傲
[考研] 344 材料专业 求调剂211 无地域要求 +8 hualkop 2026-04-11 8/400 2026-04-12 22:24 by fqwang
[考研] 296求调剂 +14 汪!?! 2026-04-10 16/800 2026-04-12 10:48 by zhouyuwinner
[考研] 电气工程专硕320求调剂 +5 小麻子111 2026-04-10 5/250 2026-04-12 10:47 by zhouyuwinner
[考研] 270求调剂 +14 杨乐369 2026-04-11 14/700 2026-04-11 20:16 by 蓝云思雨
[考研] 求调剂 +3 胃痉挛累了 2026-04-11 5/250 2026-04-11 14:13 by luhong1990
[考研] 085600材料与化工329分求调剂 +16 叶zilin 2026-04-10 16/800 2026-04-11 11:04 by may_新宇
[考研] 0854调剂 +5 音像店听花鼓戏 2026-04-10 5/250 2026-04-11 10:49 by qingpingzhu
[考研] 22408 352分求调剂0854类 +4 努力的夏末 2026-04-09 4/200 2026-04-11 09:57 by zhq0425
[考研] 263能源动力专硕求调剂 +4 加大号饭盒袋 2026-04-10 4/200 2026-04-10 20:52 by gong120082
[考研] 0858求调剂 5+5 Gky09300550, 2026-04-10 8/400 2026-04-10 19:13 by chemisry
[考研] 求调剂 +5 不会飞的鱼@ 2026-04-10 5/250 2026-04-10 19:07 by chemisry
[考研] 265求调剂 +12 风说她早忘了 2026-04-10 13/650 2026-04-10 18:56 by chemisry
信息提示
请填处理意见