24小时热门版块排行榜    

查看: 277  |  回复: 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文章,我:8.O.55.1.O.54,科目齐全,可+急 +4 gy1nBQXYQJqL 2026-08-29 5/250 2026-08-31 01:27 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.5.5.1.O.54,科目齐全,可+急 +4 gy1nBQXYQJqL 2026-08-29 6/300 2026-08-31 00:56 by hZiFeudZyoGR
[考博] 售SCI-T0P文章,我:8O.5.5.1.O.54,科目齐全,可+急 +4 ASdOkHsho7FD 2026-08-28 7/350 2026-08-31 00:21 by hZiFeudZyoGR
[基金申请] 国社科又开始会评了,不知道这次命运如何 +5 雨打竹帘 2026-08-30 9/450 2026-08-30 22:23 by 余韵清
[公派出国] 售SCI一区文章,我:8O5.5.1.O5.4,科目全,可伽急 +3 4FFAWE8HcgUD 2026-08-29 5/250 2026-08-30 20:41 by hZiFeudZyoGR
[考博] 售SCI一区文章,我:8O5.5.1.O5.4,科目全,可伽急 +3 4FFAWE8HcgUD 2026-08-29 4/200 2026-08-30 20:40 by hZiFeudZyoGR
[考研] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +3 zICmwzsBXjbN 2026-08-29 5/250 2026-08-30 20:08 by hZiFeudZyoGR
[考博] 售SCI一区T0P文章,我:8.O.55.1.O.5.4,科目全,可+急 +3 jCd0dEvKHShX 2026-08-29 3/150 2026-08-30 19:26 by hZiFeudZyoGR
[考研] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +5 G6APbkg8SA6w 2026-08-29 6/300 2026-08-30 19:02 by hZiFeudZyoGR
[论文投稿] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +4 G6APbkg8SA6w 2026-08-29 5/250 2026-08-30 19:01 by hZiFeudZyoGR
[找工作] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +6 ASdOkHsho7FD 2026-08-28 9/450 2026-08-30 11:19 by l0VvVHGBGRLv
[教师之家] 售SCI一区T0P文章,我:8.O.55.1.O54,科目全,可伽急 +5 ASdOkHsho7FD 2026-08-28 7/350 2026-08-30 06:10 by ZPa0EcMwuECS
[基金申请] 国自然评审意见 +13 wangmingqi 2026-08-28 19/950 2026-08-29 10:22 by Poppy1104
[基金申请] 系统查不到 +11 董八千 2026-08-26 11/550 2026-08-28 18:06 by Leogzhya
[基金申请] 哪位高人中了,把查询到的截图贴出来让我看看,让我长长见识 +5 yuleib84 2026-08-26 6/300 2026-08-28 00:02 by yudaoqian88
[基金申请] 看板上这么多中的,有点像50人群里49个人都是骗子的那种感觉…… +5 a089 2026-08-26 6/300 2026-08-27 14:05 by jonewore
[基金申请] 能否退出参与的面上项目解除限项 +23 koalala 2026-08-24 26/1300 2026-08-26 14:29 by 宝贝虫子
[基金申请] 为什么国自然不能直接公布 +4 bjdxyxy 2026-08-26 4/200 2026-08-26 13:12 by qingmu1201
[基金申请] 在坚冰还盖着北海的时候,我看到了怒放的梅花。 (金币+10) +6 ziyangfang 2026-08-25 9/450 2026-08-25 20:26 by huagongfeihu
信息提示
请填处理意见