焦作旅游网,纠缠不清 柠檬火焰,idea945
public class socks5proxyhelp
{
private socks5proxyhelp() { }
public static string[] errormsgs = { "operation completed successfully.",//操作成功完成 "general socks server failure.",//常规服务器失败 "connection not allowed by ruleset.",//连接不被允许 "network unreachable.",//网络不能到达 "host unreachable.",//主机不能到达 "connection refused.",//连接被拒绝 "ttl expired.",//ttl期满 "command not supported.",//不支持的命令 "address type not supported.",//不被支持的地址类型 "unknown error."//未名的错误 }; // <summary> // 连接到socks5代理 // </summary> // <param name="proxyadress">代理服务期地址</param> // <param name="proxyport">代理服务器端口</param> // <param name="destaddress">目标地址 destination: 目的地,udp命令时是本机的地址</param> // <param name="destport">目标端口,udp命令时是本机的udp端口</param> // <param name="username">用户名</param> // <param name="password">密码</param> // <returns>用于tcp连接的socket</returns> public static void connecttosocks5proxy(string proxyadress, int proxyport, string username, string password, out string errormsg) { errormsg = ""; ipaddress proxyip = null; byte[] request = new byte[257]; //请求 byte[] response = new byte[257];//应答 ushort nindex; try { proxyip = ipaddress.parse(proxyadress); } catch (formatexception) { proxyip = dns.gethostentry(proxyadress).addresslist[0]; } // 解析 destaddress (要求是类似 "212.116.65.112" 的string),否则是类似 "www.microsoft.com"的地址 ipendpoint proxyendpoint = new ipendpoint(proxyip, proxyport); socket s = null; try { s = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); s.connect(proxyendpoint);//客户端连到服务器后,然后就发送请求来协商版本和认证方法: nindex = 0; request[nindex++] = 0x05; // v 5. [版本] request[nindex++] = 0x02; // 2种验证方式 [方法的数目] request[nindex++] = 0x00; // x'00' 不需要认证 [方法1] request[nindex++] = 0x02; // x'02' 用户名/密码[方法2] s.send(request, nindex, socketflags.none); // 收到2个字节的应答,填充到response中,如果不是两个字节,则抛出异常 int ngot = s.receive(response, 2, socketflags.none); if (ngot != 2) throw new exception("从 proxy server 返回错误的应答."); // 当前定义的方法有: // x'00' 不需要认证 // x'01' gssapi // x'02' 用户名/密码 // x'03' -- x'7f' 由iana分配 // x'80' -- x'fe' 为私人方法所保留的 // x'ff' 没有可以接受的方法 switch (response[1]) { case 0xff: 没有可以接受的方法(s); break; case 0x02: 用户名密码验证(s, username, password); break; } } catch (exception ex) { errormsg = ex.message; } finally { if (s != null) { s.close(); s.dispose(); s = null; } } //sendudp.udp命令(s); } static void 没有可以接受的方法(socket s) { // 客户端没有一中验证方式能被服务器接受,则关闭该socket. s.close(); throw new exception("客户端没有一中验证方式能被代理服务器接受."); } static bool 用户名密码验证(socket s, string username, string password) { byte[] request = new byte[257]; //请求 byte[] response = new byte[257];//应答 ushort nindex; byte[] rawbytes; nindex = 0; request[nindex++] = 0x05; // version 5. 不清楚为什么报文的首字节是0x01(按照惯例应当是0x05) // 加入 user name request[nindex++] = (byte)username.length; //一个字节,放username的长度 rawbytes = encoding.default.getbytes(username); rawbytes.copyto(request, nindex); //将username 加入 nindex += (ushort)rawbytes.length; // 加入 password request[nindex++] = (byte)password.length; //一个字节,放password的长度 rawbytes = encoding.default.getbytes(password); rawbytes.copyto(request, nindex); nindex += (ushort)rawbytes.length; // 发送 username/password 请求 s.send(request, nindex, socketflags.none); int ngot = s.receive(response, 2, socketflags.none); if (ngot != 2) { throw new exception("从 proxy server 返回错误的应答."); } if (response[1] != 0x00) //返回如下的报文字节序列映像为:0x01 | 验证结果标志-->0x00 验证通过,其余均表示有故障 { throw new exception("账号或密码错误!"); } console.writeline("okpass"); return true; } }
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Blazor server side 自家的一些开源的, 实用型项目的进度之 CEF客户端
.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)
vue+.netcore可支持业务代码扩展的开发框架 VOL.Vue 2.0版本发布
网友评论