http://www.cnblogs.com/zhujiechang/archive/2008/10/21/1316308.html
这里主要讲的是用.NET实现基于Socket5下面的代理协议进行客户端的通讯,Socket4的实现是类似的,注意的事,这里不是讲用C#实现一个代理服务器,因为实现一个代理服务器需要实现很多协议,头大,而且现在市面上有很多现成的代理服务器用,性能又好,直接用不好吗?而是用C#来实现客户端通过一个代理服务器进行Socket5的通讯,这个简单点,一般来说用Socket5就好了,Socket4现在也逐渐淘汰,基本上代理服务器都支持Socket5。
首先我们要了解下Socket5的代理协议是基于TCP协议之上的,从Socket4扩展上来的,用于提供给其他协议例如HTTP、FTP所作用的一套防火墙协议。
(这里做点小解释,实际上应该是SOCKS V5协议,但是目前网上都用Socket5这样称呼,目前本文也暂时这样称)
然后下面简单的说下该协议的内容,具体分为两部分:
一部分是基于TCP协议的客户
当一个基于TCP协议的客户端希望与一个只能通过防火墙可以到达的目标(这是由实现所决定的)建立连接,它必须先建立一个与SOCKS服务器上SOCKS 端口的TCP连接。通常这个TCP端口是1080。当连接建立后,客户端进入协议的“握手(negotiation)”过程:认证方式的选择,根据选中的方式进行认证,然后发送转发的要求。SOCKS服务器检查这个要求,根据结果,或建立合适的连接,或拒绝。是不是有点像FTP?差不多。
握手的过程:
客户端连到服务器后,然后就发送请求来协商版本和认证方法:
VER NMETHODS METHODS
1 1 1 to 255
这个版本的SOCKS协议中,VER字段被设置成X'05'。NMETHODS字段包含了在METHODS字段中出现的方法标示的数目(以字节为单位)。简化就是像服务器发送05 01 00
服务器从这些给定的方法中选择一个并发送一个方法选中的消息回客户端:
VER METHOD
1 1
如果选中的消息是X’FF’,这表示客户端所列出的方法列表中没有一个方法被选中,客户端必须关闭连接。
这里我们关注的是 X’00’ 不需要认证和X’02’ 用户名/密码,简化是服务器会返回的前两个字节
会是05 00或者05 02,02的时候进行验证。
验证过程结束后,客户端就发送详细的请求信息。如果协商的方法中有以完整性检查和/或安全性为目的的封装,这些请求必须按照该方法所定义的方式进行封装。
握手完成之后,要进行一个请求连接,这个就是对远程服务器的连接,我们知道当前既然连接的是代理服务器,我们实际上发送数据的对象并不是它,也就是我们要告诉代理服务器去连接真实的某某,现在就是在做这一步了。
SOCKS请求的格式如下:
VER CMD RSV ATYP DST.ADDR DST.PROT
1 1 X’00’ 1 Variable 2
其中
· VER 协议版本: X’05’
· CMD
· CONNECT:X’01’
· BIND:X’02’
· UDP ASSOCIATE:X’03’
· RSV 保留
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’'
· DST.ADDR 目的地址
· DST.PORT 以网络字节顺序出现的端口号
SOCKS服务器会根据源地址和目的地址来分析请求,然后根据请求类型返回一个或多个应答。
ATYP字段中描述了地址字段(DST.ADDR,BND.ADDR)所包含的地址类型:
· X'01'
基于IPV4的IP地址,4个字节长
· X'03'
基于域名的地址,地址字段中的第一字节是以字节为单位的该域名的长度,没有结尾的NUL字节。
· X'04'
基于IPV6的IP地址,16个字节长。
Variable表示该域的长度是可变的。
以最常用的IP表示法为例,加入我们的代理服务器地址是10.10.1.254,现在我们要通过代理服务器访问192.168.1.2这个IP地址,这里不要看做局域网地址,因为是通过代理进行访问的,
前期传递了IP对象IPEndPoint destIP;
byte [] data = new byte[10];
data[0]=5;data[1]=1;data[2]=0;data[3]=1;//前4个字节
Array.Copy(destIP.Address.GetAddressBytes(), 0, data, 4, 4); //IP地址
Array.Copy(BitConverter.GetBytes(
IPAddress.HostToNetworkOrder(destIP.Port)), 2, data, 8, 2); //端口号
这个data就是要发送的请求了.
代理服务器这边会根据请求,以如下格式返回:
VER REP RSV ATYP BND.ADDR BND.PORT
1 1 X’00’ 1 Variable 2
其中:
· VER 协议版本: X’05’
· REP 应答字段:
· X’00’ 成功
· X’01’ 普通的SOCKS服务器请求失败
· X’02’ 现有的规则不允许的连接
· X’03’ 网络不可达
· X’04’ 主机不可达
· X’05’ 连接被拒
· X’06’ TTL超时
· X’07’ 不支持的命令
· X’08’ 不支持的地址类型
· X’09’ – X’FF’ 未定义
· RSV 保留
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’
· BND.ADDR 服务器绑定的地址
· BND.PORT 以网络字节顺序表示的服务器绑定的段口
标识为RSV的字段必须设为X’00’。
返回的信息里面都看到,最重要是第二个域,如果为0,就表示成功,这第二个域对于接收到bytes来说是第1个字节,及data[1].
如果选中的方法中有以完整性检查和/或安全性为目的的封装,这些应答必须按照该方法所定义的方式进行封装。
完成这步请求就完成了Socket5整个TCP客户端的连接了,剩下的工作,你就如正常的连接一下向代理服务器发送数据,简单来说这时候你就把代理服务器看成远程你要连接的对象就行了,代理服务器此时就是个透明的网络连接。至于整个C#示例,可以到我的空间下载,这个是博客园文件下载链接。
对于UDP的客户端连接,这里给出协议规范,可以自行进行实验。
在UDP ASSOCIATE应答中由BND.PORT指明了服务器所使用的UDP端口,一个基于UDP协议的客户必须发送数据报至UDP转发服务器的该端口上。如 果协商的认证方法中有以完整性、认证和/或安全性为目的的封装,这些数据报必须按照该方法所定义的方式进行封装。每个UDP数据报都有一个UDP请求头在 其首部:
RSV FRAG ATYP DST.ADDR DST.PORT DATA
2 1 1 Variable 2 Variable
在UDP请求头中的字段是:
· RSV 保留 X’0000’
· FRAG 当前的分段号
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’
· DST.ADDR 目的地址
· DST.PORT 以网络字节顺序出现的端口号
· DATA 用户数据
当一个UDP转发服务器转发一个UDP数据报时,不会发送任何通知给客户端;同样,它也将丢弃任何它不能发至远端主机的数据报。当UDP转发服务器从远端服务器收到一个应答的数据报时,必须加上上述UDP请求头,并对数据报进行封装。
UDP转发服务器必须从SOCKS服务器得到期望的客户端IP地址,并将数据报发送到UDP ASSOCIATE应答中给定的端口号。如果数据报从任何IP地址到来,而该IP地址与该特定连接中指定的IP地址不同,那么该数据报会被丢弃。
FRAG字段指明数据报是否是一些分片中的一片。如果SOCKS服务器要实现这个功能,X’00’指明数据报是独立的;其他则越大越是数据报的尾端。介于 1到127之间的值说明了该分片在分片序列里的位置。每个接收者都为这些分片提供一个重组队列和一个重组的计时器。这个重组队列必须在重组计时器超时后重 新初始化,并丢弃相应的数据报。或者当一个新到达的数据报有一个比当前在处理的数据报序列中最大的FRAG值要小时,也必须重新初始化从组队列。重组计时 器必须小于5秒。只要有可能,应用程序最好不要使用分片。
分片的实现是可选的;如果某实现不支持分片,所有FRAG字段不为0的数据报都必须被丢弃。
一个SOCKS的UDP编程界面(The programming interface for a SOCKS-aware UDP)必须报告当前可用UDP数据报缓存空间小于操作系统提供的实际空间。
· 如果 ATYP是 X’01’ - 10+method_dependent octets smaller
· 如果 ATYP是X’03’ - 262+method_dependent octets smaller
· 如果 ATYP是X’04’ - 20+method_dependent octets smaller
首先我们要了解下Socket5的代理协议是基于TCP协议之上的,从Socket4扩展上来的,用于提供给其他协议例如HTTP、FTP所作用的一套防火墙协议。
(这里做点小解释,实际上应该是SOCKS V5协议,但是目前网上都用Socket5这样称呼,目前本文也暂时这样称)
然后下面简单的说下该协议的内容,具体分为两部分:
一部分是基于TCP协议的客户
当一个基于TCP协议的客户端希望与一个只能通过防火墙可以到达的目标(这是由实现所决定的)建立连接,它必须先建立一个与SOCKS服务器上SOCKS 端口的TCP连接。通常这个TCP端口是1080。当连接建立后,客户端进入协议的“握手(negotiation)”过程:认证方式的选择,根据选中的方式进行认证,然后发送转发的要求。SOCKS服务器检查这个要求,根据结果,或建立合适的连接,或拒绝。是不是有点像FTP?差不多。
握手的过程:
客户端连到服务器后,然后就发送请求来协商版本和认证方法:
VER NMETHODS METHODS
1 1 1 to 255
这个版本的SOCKS协议中,VER字段被设置成X'05'。NMETHODS字段包含了在METHODS字段中出现的方法标示的数目(以字节为单位)。简化就是像服务器发送05 01 00
服务器从这些给定的方法中选择一个并发送一个方法选中的消息回客户端:
VER METHOD
1 1
如果选中的消息是X’FF’,这表示客户端所列出的方法列表中没有一个方法被选中,客户端必须关闭连接。
这里我们关注的是 X’00’ 不需要认证和X’02’ 用户名/密码,简化是服务器会返回的前两个字节
会是05 00或者05 02,02的时候进行验证。
验证过程结束后,客户端就发送详细的请求信息。如果协商的方法中有以完整性检查和/或安全性为目的的封装,这些请求必须按照该方法所定义的方式进行封装。
握手完成之后,要进行一个请求连接,这个就是对远程服务器的连接,我们知道当前既然连接的是代理服务器,我们实际上发送数据的对象并不是它,也就是我们要告诉代理服务器去连接真实的某某,现在就是在做这一步了。
SOCKS请求的格式如下:
VER CMD RSV ATYP DST.ADDR DST.PROT
1 1 X’00’ 1 Variable 2
其中
· VER 协议版本: X’05’
· CMD
· CONNECT:X’01’
· BIND:X’02’
· UDP ASSOCIATE:X’03’
· RSV 保留
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’'
· DST.ADDR 目的地址
· DST.PORT 以网络字节顺序出现的端口号
SOCKS服务器会根据源地址和目的地址来分析请求,然后根据请求类型返回一个或多个应答。
ATYP字段中描述了地址字段(DST.ADDR,BND.ADDR)所包含的地址类型:
· X'01'
基于IPV4的IP地址,4个字节长
· X'03'
基于域名的地址,地址字段中的第一字节是以字节为单位的该域名的长度,没有结尾的NUL字节。
· X'04'
基于IPV6的IP地址,16个字节长。
Variable表示该域的长度是可变的。
以最常用的IP表示法为例,加入我们的代理服务器地址是10.10.1.254,现在我们要通过代理服务器访问192.168.1.2这个IP地址,这里不要看做局域网地址,因为是通过代理进行访问的,
前期传递了IP对象IPEndPoint destIP;
byte [] data = new byte[10];
data[0]=5;data[1]=1;data[2]=0;data[3]=1;//前4个字节
Array.Copy(destIP.Address.GetAddressBytes(), 0, data, 4, 4); //IP地址
Array.Copy(BitConverter.GetBytes(
IPAddress.HostToNetworkOrder(destIP.Port)), 2, data, 8, 2); //端口号
这个data就是要发送的请求了.
代理服务器这边会根据请求,以如下格式返回:
VER REP RSV ATYP BND.ADDR BND.PORT
1 1 X’00’ 1 Variable 2
其中:
· VER 协议版本: X’05’
· REP 应答字段:
· X’00’ 成功
· X’01’ 普通的SOCKS服务器请求失败
· X’02’ 现有的规则不允许的连接
· X’03’ 网络不可达
· X’04’ 主机不可达
· X’05’ 连接被拒
· X’06’ TTL超时
· X’07’ 不支持的命令
· X’08’ 不支持的地址类型
· X’09’ – X’FF’ 未定义
· RSV 保留
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’
· BND.ADDR 服务器绑定的地址
· BND.PORT 以网络字节顺序表示的服务器绑定的段口
标识为RSV的字段必须设为X’00’。
返回的信息里面都看到,最重要是第二个域,如果为0,就表示成功,这第二个域对于接收到bytes来说是第1个字节,及data[1].
如果选中的方法中有以完整性检查和/或安全性为目的的封装,这些应答必须按照该方法所定义的方式进行封装。
完成这步请求就完成了Socket5整个TCP客户端的连接了,剩下的工作,你就如正常的连接一下向代理服务器发送数据,简单来说这时候你就把代理服务器看成远程你要连接的对象就行了,代理服务器此时就是个透明的网络连接。至于整个C#示例,可以到我的空间下载,这个是博客园文件下载链接。
对于UDP的客户端连接,这里给出协议规范,可以自行进行实验。
在UDP ASSOCIATE应答中由BND.PORT指明了服务器所使用的UDP端口,一个基于UDP协议的客户必须发送数据报至UDP转发服务器的该端口上。如 果协商的认证方法中有以完整性、认证和/或安全性为目的的封装,这些数据报必须按照该方法所定义的方式进行封装。每个UDP数据报都有一个UDP请求头在 其首部:
RSV FRAG ATYP DST.ADDR DST.PORT DATA
2 1 1 Variable 2 Variable
在UDP请求头中的字段是:
· RSV 保留 X’0000’
· FRAG 当前的分段号
· ATYP 后面的地址类型
· IPV4:X’01’
· 域名:X’03’
· IPV6:X’04’
· DST.ADDR 目的地址
· DST.PORT 以网络字节顺序出现的端口号
· DATA 用户数据
当一个UDP转发服务器转发一个UDP数据报时,不会发送任何通知给客户端;同样,它也将丢弃任何它不能发至远端主机的数据报。当UDP转发服务器从远端服务器收到一个应答的数据报时,必须加上上述UDP请求头,并对数据报进行封装。
UDP转发服务器必须从SOCKS服务器得到期望的客户端IP地址,并将数据报发送到UDP ASSOCIATE应答中给定的端口号。如果数据报从任何IP地址到来,而该IP地址与该特定连接中指定的IP地址不同,那么该数据报会被丢弃。
FRAG字段指明数据报是否是一些分片中的一片。如果SOCKS服务器要实现这个功能,X’00’指明数据报是独立的;其他则越大越是数据报的尾端。介于 1到127之间的值说明了该分片在分片序列里的位置。每个接收者都为这些分片提供一个重组队列和一个重组的计时器。这个重组队列必须在重组计时器超时后重 新初始化,并丢弃相应的数据报。或者当一个新到达的数据报有一个比当前在处理的数据报序列中最大的FRAG值要小时,也必须重新初始化从组队列。重组计时 器必须小于5秒。只要有可能,应用程序最好不要使用分片。
分片的实现是可选的;如果某实现不支持分片,所有FRAG字段不为0的数据报都必须被丢弃。
一个SOCKS的UDP编程界面(The programming interface for a SOCKS-aware UDP)必须报告当前可用UDP数据报缓存空间小于操作系统提供的实际空间。
· 如果 ATYP是 X’01’ - 10+method_dependent octets smaller
· 如果 ATYP是X’03’ - 262+method_dependent octets smaller
· 如果 ATYP是X’04’ - 20+method_dependent octets smaller
相关推荐
socks5 c#简单代理源码 socks5 c#简单代理源码 socks5 c#简单代理源码 socks5 c#简单代理源码
用C#实现的SOCKS5代理服务器源代码.rar
C# socks5服务端,终端程序源码。编译仅仅12K
用C#实现的SOCKS5代理服务器源代码分享给大家
C# SOCKS client 类库,Socks4Client类、Socks4aClient类、Socks5Client类分别封装了socks4\4a\5的协议,方便你在代码里面直接使用socks代理。还有其它很多的工具类,比如FtpsClient、HttpClient
C#写的代理服务器源代码 功能强大 支持http和socks5 支持配置 支持用户名密码验证 可以自己修改加入日志功能 支持多IP 国外网站上找的,非常强
C# 网络传输文件 socks 网络编程
用C#写的 用socks 通信的 demo 用vs2010 写的 winform 能客户端发信息到服务器 然后转发 服务器发信息给客户端
在实际学习中,由于在有些软件用到了socks5(如oicq,icq等),对其原理不甚了解,相信很多朋友对其也不是很了解,于是我仔细研读了一下rfc1928,觉得有必要译出来供大家参考。
HttpToSocks5Proxy 使用.NET HttpClient时,该库允许您通过Socks5代理进行连接。 它实现了IWebProxy接口,因此可以与所有支持HTTP / HTTPS代理的库一起使用。HttpClient的用法 using MihaZupan ;var proxy = new ...
作者:Kingthy早上看到breeze写了一篇Socks5代理协议的文章《C# 实现Socket5代理协议通讯 》,并在评论里看到howaaa说“顺便也讲讲用C#实现一个Socks5代理服务器吧,这方面资料很少,相信很有价值”,于是一时兴起,...
Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTPS或SOCKS代理或代理链。
易语言纯命令的socks5服务器源码,如果连接数超过了100,请自行修改对应算法和数组。@易语言学习论坛-落叶兰。
Socks5进程代理DLL,配套调用表,在压缩包里面
c# Socks4 Socks4a Socks5 HttpProxy 测试通过
用途是连接一个socks5服务器(HTTP或socks5),然后在本地监听一个端口提供HTTP代理服务.DLL是C++的。附件里面有 LibPrivoxy.dll 源码下载地址.调用例子很简单没啥技术含量,感觉HTTP代理用途有点局限,需要的下载。...
另一个代理客户端源码,基于c#,.net框架,代码相交简单。比较实用
CSharp 中的 Socks 5 服务器实现RFC 参考: : 用 C# 编写的功能性工作袜子 5 服务器。 支持 IPv4 和 IPv6。 连接命令工作正常(TCP) Udp 合作伙伴正在进行中不计划支持绑定命令支持插件数据库连接(登录、统计、...
socks5服务器源代码 基于linux c epoll实现 搭建与云服务器 火狐浏览器测试 运行./ss即可 火狐设置socks5代理 你的服务器IP:1200