在实际使用的过程中可能存在使用代理访问其他网站,以防因过度频繁访问,自己ip被封,如下提供C#使用socks5的大致代码,个人可以根据实际情况进行封装、加工。切勿乱用
public class LoadProxyHelper { private static readonly log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // 默认使用array 可以根据自己的爱好调整 private static string[] ipdatas = new string[20]; // 如下代理ip未必可用,请自行找寻(本次只是作为一个样本) private static string ipFormat = "x.x.x.{0}"; static LoadProxyHelper() { // 给的是固定的ip for (int i = 0; i < ipdatas.Length; i++) { ipdatas[i] = string.Format(ipFormat , 19+i); } } public bool m_RequireAuthorize = false; public string m_user = string.Empty; public string m_pass = string.Empty; public byte[] bytes = new byte[1024]; ////// 设定byte /// public byte[] RequireBytes { get { return bytes; } set { bytes = value; } } ////// default is false /// public bool RequireAuthorize { get { return m_RequireAuthorize; } set { m_RequireAuthorize = value; } } public string Username { get { return m_pass; } set { m_pass = value; } } public string Password { get { return m_user; } set { m_user = value; } } private static string GetEncodType(string ContentType) { string strTemp = string.Empty; strTemp = ContentType; if (strTemp != null && strTemp.IndexOf("charset") > -1) { int index = strTemp.IndexOf("charset=") + 8; strTemp = strTemp.Substring(index, strTemp.Length - index); return strTemp; } return Encoding.Default.BodyName; } ////// 获取请求返回的结果 /// 注意包头中的每一个内容后面不能缺失“\r\n” /// 同时注意targetHost需要为域名 /// ///public string GetSocketBytes(string targetHost,int targetPort,string request,string encode,string refer="") { try { string messages = string.Empty; int rl = 0; string sr = string.Empty; Random rand = new Random(); string ip = ipdatas[rand.Next(0, 20)]; Socket sRH = GetSocket(ip, 8080); ConnectProxyServer(targetHost, targetPort, sRH); SocketSend(request + "\r\n", sRH); SocketSend("Accept-Language:zh-CN,zh;q=0.8\r\n", sRH); SocketSend("Connection:close\r\n", sRH); SocketSend(string.Format("Host:{0}\r\n", targetHost), sRH); SocketSend("User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36\r\n", sRH); SocketSend("\r\n", sRH); rl = sRH.Receive(bytes); sr = Encoding.GetEncoding(GetEncodType(encode)).GetString(bytes, 0, rl); //sr = GetResponseByEncode(encode, rl); StringBuilder messDatas = new StringBuilder(); while (sr.Length > 0) { rl = sRH.Receive(bytes); //sr = GetResponseByEncode(encode, rl); sr = Encoding.GetEncoding(GetEncodType(encode)).GetString(bytes, 0, rl); messDatas.Append(sr); Console.WriteLine(sr); } if (!string.IsNullOrWhiteSpace(messDatas.ToString())) { messages = messDatas.ToString(); } return messages; } catch(Exception ex) { StringBuilder sblog = new StringBuilder(); sblog.AppendFormat("{0}异常信息( GetSocketBytes ):", "LoadProxyHelper"); sblog.AppendFormat("{0}ex:{1},", Environment.NewLine, ex.ToString()); sblog.AppendFormat("{0}StackTrace:{1},", Environment.NewLine, ex.StackTrace.ToString()); _logger.Fatal(sblog.ToString(), ex); } return ""; } /// /// 获取response内容 /// /// /// ///private string GetResponseByEncode(string encode,int rl) { string sr = string.Empty; switch (encode) { case "utf-8": sr = Encoding.UTF8.GetString(bytes, 0, rl); break; case "ascii": sr = Encoding.ASCII.GetString(bytes, 0, rl); break; case "unicode": sr = Encoding.Unicode.GetString(bytes, 0, rl); break; default: sr = Encoding.Default.GetString(bytes, 0, rl); break; } return sr; } /// /// 发送请求 /// /// /// private void SocketSend(string str, Socket sRH) { try { byte[] b = Encoding.Default.GetBytes(str); sRH.Send(b); } catch (Exception ex) { StringBuilder sblog = new StringBuilder(); sblog.AppendFormat("{0}异常信息( SocketSend ):", "LoadProxyHelper"); sblog.AppendFormat("{0}ex:{1},", Environment.NewLine, ex.ToString()); sblog.AppendFormat("{0}StackTrace:{1},", Environment.NewLine, ex.StackTrace.ToString()); _logger.Fatal(sblog.ToString(), ex); } } ////// 连接代理服务器 /// /// /// /// ///public bool ConnectProxyServer(string strRemoteHost, int iRemotePort, Socket sProxyServer) { try { //构造Socks5代理服务器第一连接头(无用户名密码) byte[] bySock5Send = new Byte[10]; bySock5Send[0] = 5; bySock5Send[1] = 1; bySock5Send[2] = RequireAuthorize ? (byte)2 : (byte)0; //发送Socks5代理第一次连接信息 sProxyServer.Send(bySock5Send, 3, SocketFlags.None); byte[] bySock5Receive = new byte[10]; int iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None); //用户验证 if (bySock5Receive[1] == 2 && !RequireAuthorize) { throw new Exception("代理服务器需要进行身份确认。"); } else if (bySock5Receive[1] == 2) { //构造Socks5代理服务器第一连接头(无用户名密码) byte[] bUser = Encoding.Default.GetBytes(Username); byte[] bPass = Encoding.Default.GetBytes(Password); int dl = 3 + bUser.Length + bPass.Length; bySock5Send = new Byte[dl]; bySock5Send[0] = 5; bySock5Send[1] = (byte)bUser.Length; Array.Copy(bUser, 0, bySock5Send, 2, bUser.Length); bySock5Send[2 + bUser.Length] = (byte)bPass.Length; Array.Copy(bPass, 0, bySock5Send, 3 + bUser.Length, bPass.Length); //发送Socks5代理第一次连接信息 sProxyServer.Send(bySock5Send, dl, SocketFlags.None); bySock5Receive = new byte[100]; iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None); } if (iRecCount < 2) { sProxyServer.Close(); throw new Exception("不能获得代理服务器正确响应。"); } if (bySock5Receive[0] != 5 || (bySock5Receive[1] != 0 && bySock5Receive[1] != 2)) { sProxyServer.Close(); throw new Exception("代理服务其返回的响应错误。"); } if (bySock5Receive[1] == 0) { bySock5Send[0] = 5; bySock5Send[1] = 1; bySock5Send[2] = 0; bySock5Send[3] = 1; IPAddress ipAdd = Dns.Resolve(strRemoteHost).AddressList[0]; string strIp = ipAdd.ToString(); string[] strAryTemp = strIp.Split(new char[] { '.' }); bySock5Send[4] = Convert.ToByte(strAryTemp[0]); bySock5Send[5] = Convert.ToByte(strAryTemp[1]); bySock5Send[6] = Convert.ToByte(strAryTemp[2]); bySock5Send[7] = Convert.ToByte(strAryTemp[3]); bySock5Send[8] = (byte)(iRemotePort / 256); bySock5Send[9] = (byte)(iRemotePort % 256); sProxyServer.Send(bySock5Send, bySock5Send.Length, SocketFlags.None); iRecCount = sProxyServer.Receive(bySock5Receive, bySock5Receive.Length, SocketFlags.None); if (bySock5Receive[0] != 5 || bySock5Receive[1] != 0) { sProxyServer.Close(); throw new Exception("第二次连接Socks5代理返回数据出错。"); } return true; } else { if (bySock5Receive[1] == 2) throw new Exception("代理服务器需要进行身份确认。"); else return false; } } catch(Exception ex) { StringBuilder sblog = new StringBuilder(); sblog.AppendFormat("{0}异常信息( ConnectProxyServer ):", "LoadProxyHelper"); sblog.AppendFormat("{0}ex:{1},", Environment.NewLine, ex.ToString()); sblog.AppendFormat("{0}StackTrace:{1},", Environment.NewLine, ex.StackTrace.ToString()); _logger.Fatal(sblog.ToString(), ex); } return false; } /// /// 获取连接的socket /// /// /// ///public Socket GetSocket(string strIpAdd, int iPort) { try { IPAddress hostadd = IPAddress.Parse(strIpAdd);//Dns.Resolve(strIpAdd).AddressList[0]; IPEndPoint EPhost = new IPEndPoint(hostadd, iPort); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Connect(EPhost); return s; } catch (Exception ex) { StringBuilder sblog = new StringBuilder(); sblog.AppendFormat("{0}异常信息( GetSocket ):", "LoadProxyHelper"); sblog.AppendFormat("{0}ex:{1},", Environment.NewLine, ex.ToString()); sblog.AppendFormat("{0}StackTrace:{1},", Environment.NewLine, ex.StackTrace.ToString()); _logger.Fatal(sblog.ToString(), ex); throw (ex); } } }
调用代码
string host = "www.baidu.com"; string encode = "UTF-8"; string requset = string.Format("GET / HTTP/1.1"); // socks5 strReceiveString = proxHelper.GetSocketBytes(host, 80, requset, encode); 根据实际情况填写
关于socks5发送请求的包头,请参考附件图片自行添加或修改
如上基本上实现一个通过C#+socks5完成代理操作
关于socks5说明请参阅:http://www.cnblogs.com/zhujiechang/archive/2008/10/21/1316308.html