使用Socks5代理服务器连接网络

来源:互联网 发布:读英语软件 编辑:程序博客网 时间:2024/04/27 08:21

    /// <summary>
    /// 使用Socks5代理服务器连接网络
    /// </summary>
    class SockProxy
    {
        bool m_RequireAuthorize = false;
        string m_user = string.Empty;
        string m_pass = string.Empty;

        /// <summary>
        /// default is false
        /// </summary>
        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; }
        }

        public bool ConnectProxyServer(string strRemoteHost, int iRemotePort, Socket sProxyServer)
        {
            //构造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;
            }
            return false;
        }

        public Socket GetSocket(string strIpAdd, int iPort)
        {
            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;
        }
    }
//用法示例:

        private void Form1_Load(object sender, EventArgs e)
        {
            string proxyHost = "10.32.32.51";// "10.4.8.1";//
            int proxyProt = 1080;

            byte[] b;
            int rl = 0;
            string sr;

            SockProxy p = new SockProxy();

            {//如果不需要密码验证,略去这段代码
                p.RequireAuthorize = true;
                p.Username = "jerry";
                p.Password = "456321";
            }
            Socket sRH = p.GetSocket(proxyHost, proxyProt);

            p.ConnectProxyServer("10.32.9.16", 9160, sRH);
            b = Encoding.Default.GetBytes("GET /WAP/Default.aspx HTTP/1.0");
            sRH.Send(b);
            b = new byte[4096];
            rl = sRH.Receive(b);
            sr = Encoding.Default.GetString(b, 0, rl);
            MessageBox.Show(sr);
        }

 
原创粉丝点击