0

我查看了相关的链接。我找不到任何东西。请帮帮我。这是我的代码。(VS2010)

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://whatismyipaddress.com/");
        request.Proxy = new WebProxy("127.0.0.1:9150");
        request.KeepAlive = false;

        try
        {
            using (var response = request.GetResponse())
            {
                using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
                {
                    string temp = reader.ReadToEnd();
                    MessageBox.Show(temp);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

这会带来这样的错误消息。(501) 未实施。

托尔说。

Socks 版本 71 无法识别。(Tor 不是 http 代理)

怎么了?有人帮帮我。

4

2 回答 2

1

不幸的是,经过一番挖掘之后,TOR 不是 HTTP 代理。它是一个 SOCKS 代理,您可以使用 Privoxy 之类的允许 sock 转发的东西。

使用 Tor 作为代理

如何将 Privoxy 与 TOR 一起使用:http: //www.privoxy.org/faq/misc.html#TOR

于 2013-07-18T09:35:05.157 回答
1

我创建了以下类 (HttpOverSocksProxy) 来将我的 http 请求路由到 Tor socks 代理。

它通过以下方式做到这一点:

  1. 在本地端口(例如 127.0.0.1:9091)上侦听传入的 http 请求
  2. 从这些请求的标头中获取主机
  3. 通过 Tor 打开与该主机的连接
  4. 将所有数据(GET\POST、headers、body)从源连接复制到 Tor 连接,反之亦然
  5. 然后像您在上面所做的那样发出 Http 请求,但在上述情况下,WebProxy 设置为 http\socks 代理,这将是 127.0.0.1:9091

请注意,不支持 https 请求,您将收到来自网络服务器的 400 错误

我正在使用 Mentalis 类 ProxySocket 将 Socks 连接包装为标准套接字 http://www.mentalis.org/soft/class.qpx?id=9

此代码尚未经过彻底测试,但到目前为止它工作正常。

HttpOverSocksProxy 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;
using Org.Mentalis.Network.ProxySocket;
using System.IO;

namespace ConsoleApplication1
{
    /*
     * HTTPS is not supported, it will probably result in a (400) 'Bad Request' response. 
     */

    public class HttpOverSocksProxy
    {
        private class Connection
        {
            public IPLocation host_loc;
            public bool host_found = false;
            public bool host_connected = false; //if have_found==true && host_connected==false then we are currently connecting to the host
            public long host_last_read_pos = 0;

            public NetworkStream client_stream = null;
            public TcpClient client_tcp = null;

            public NetworkStream host_stream = null;
            public ProxySocket host_socket = null;

            public byte[] client_buf_ary = null;
            public byte[] host_buf_ary = null;
            public MemoryStream buf_str = null;

            public Connection(NetworkStream str,TcpClient client,int buffer_size)
            {
                this.client_stream = str;
                this.client_tcp = client;
                this.host_buf_ary = new byte[buffer_size];
                this.client_buf_ary = new byte[buffer_size];
                this.buf_str = new MemoryStream(buffer_size);
            }
        }

        private struct IPLocation
        {
            public string host;
            public int port;

            public IPLocation(string host, int port)
            {
                this.host = host;
                this.port = port;
            }
        }

        private TcpListener _tcp_server;
        private List<Connection> _connections = new List<Connection>();

        public IPEndPoint EndPoint_Source_Http { get; private set; }
        public IPEndPoint EndPoint_Destination_Socks { get; private set; }
        public ProxyTypes SocksProxyType { get; private set; }
        public int Buffer_Size { get; private set; }

        public HttpOverSocksProxy(IPEndPoint http_listen, IPEndPoint socks_proxy, ProxyTypes socks_proxy_type, int buffer_size = 1024*4)
        {
            this.EndPoint_Source_Http = http_listen;
            this.EndPoint_Destination_Socks = socks_proxy;
            this.SocksProxyType = socks_proxy_type;
            this.Buffer_Size = buffer_size;
        }

        public void Start()
        {
            _tcp_server = new TcpListener(EndPoint_Source_Http);
            _tcp_server.Start();
            _tcp_server.BeginAcceptTcpClient(Client_Accept, _tcp_server);
        }

        public void Stop()
        {
            lock (_connections)
            {
                _tcp_server.Stop();
                _connections.ForEach(a => Close(a));
                _connections.Clear();
            }
        }

        private void Client_Accept(IAsyncResult result)
        {
            TcpListener tcp_server = result.AsyncState as TcpListener;

            if (tcp_server != null)
            {
                TcpClient tcp_client = tcp_server.EndAcceptTcpClient(result);

                if (tcp_client != null)
                {
                    Connection conn = new Connection(tcp_client.GetStream(), tcp_client, Buffer_Size);

                    lock (_connections)
                    {
                        _connections.Add(conn);
                    }

                    conn.client_stream.BeginRead(conn.client_buf_ary, 0, Buffer_Size, Client_Write, conn);
                }

                tcp_server.BeginAcceptTcpClient(Client_Accept, tcp_server);
            }
        }

        private void Client_Write(IAsyncResult result)
        {
            Connection conn = result.AsyncState as Connection;

            if (conn != null)
            {
                try
                {
                    int len = conn.client_stream.EndRead(result);

                    if (len == 0) // Client has closed the connection
                    {
                        Close(conn);
                    }
                    else
                    {
                        lock (conn)
                        {
                            if (conn.host_connected)
                            {
                                try
                                {
                                    conn.host_stream.Write(conn.client_buf_ary, 0, len); //we want this to block
                                }
                                catch (Exception e_h)
                                {
                                    if (!Handle_Disposed(e_h, conn))
                                        throw;
                                }
                            }
                            else
                                conn.buf_str.Write(conn.client_buf_ary, 0, len);

                            if (!conn.host_found)
                                OpenHostConnection(conn);

                            conn.client_stream.BeginRead(conn.client_buf_ary, 0, Buffer_Size, Client_Write, conn);
                        }
                    }
                }
                catch (Exception e_c)
                {
                    if (!Handle_Disposed(e_c, conn))
                        throw;
                }
            }
        }

        private void OpenHostConnection(Connection conn)
        {
            if (conn.host_found)
                throw new Exception("Already have host");   //should never happen

            #region Get Host from headers
            {
                MemoryStream str_mem = conn.buf_str;
                str_mem.Position = conn.host_last_read_pos;

                string raw_host_line;
                while ((raw_host_line = ReadLine(str_mem, ASCIIEncoding.ASCII)) != null)
                {
                    conn.host_last_read_pos = str_mem.Position;

                    if (raw_host_line.Length == 0)
                        throw new Exception("Failed to find Host in request headers");

                    int idx_split;
                    if ((idx_split = raw_host_line.IndexOf(':')) > 0 && idx_split < raw_host_line.Length)
                    {
                        string key = raw_host_line.Substring(0, idx_split);
                        string val = raw_host_line.Substring(idx_split + 1).Trim();

                        if (key.Equals("host", StringComparison.InvariantCultureIgnoreCase))
                        {
                            string[] host_parts = val.Split(':');

                            if (host_parts.Length == 1)
                            {
                                conn.host_loc = new IPLocation(host_parts[0], 80);
                            }
                            else if (host_parts.Length == 2)
                            {
                                conn.host_loc = new IPLocation(host_parts[0], Int32.Parse(host_parts[1]));
                            }
                            else
                                throw new Exception(String.Format("Failed to parse HOST from '{0}'", raw_host_line));

                            conn.host_found = true;
                        }
                    }
                }

                str_mem.Seek(0,SeekOrigin.End);
            }
            #endregion

            #region Open Host Connection
            {
                if (conn.host_found)
                {
                    try
                    {
                        ProxySocket skt = new ProxySocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        skt.ProxyEndPoint = EndPoint_Destination_Socks;
                        skt.ProxyType = ProxyTypes.Socks5;
                        conn.host_socket = skt;

                        if (conn.host_loc.port == 443)
                            Console.WriteLine("HTTPS is not suported.");

                        skt.BeginConnect(conn.host_loc.host, conn.host_loc.port, Host_Connected, conn);
                    }
                    catch (ObjectDisposedException e)
                    {
                        if (!Handle_Disposed(e, conn))
                            throw;
                    }
                }
            }
            #endregion
        }

        private void Host_Connected(IAsyncResult result)
        {
            Connection conn = result.AsyncState as Connection;

            if (conn != null)
            {
                lock (conn) //Need to set up variables and empty buffer, cant have the Client writing to the host stream during this time
                {
                    try
                    {
                        conn.host_socket.EndConnect(result);
                        conn.host_stream = new NetworkStream(conn.host_socket);
                        conn.host_connected = true;

                        conn.buf_str.Position = 0;
                        conn.buf_str.CopyTo(conn.host_stream);

                        conn.host_stream.BeginRead(conn.host_buf_ary, 0, Buffer_Size, Host_Write, conn);
                    }
                    catch (Exception e)
                    {
                        if (!Handle_Disposed(e, conn))
                            throw;
                    }
                }
            }
        }

        private void Host_Write(IAsyncResult result)
        {
            Connection conn = result.AsyncState as Connection;

            if (conn != null)
            {
                try
                {
                    int len = conn.host_stream.EndRead(result);

                    if (len == 0)
                    {
                        Close(conn);
                    }
                    else
                    {
                        try
                        {
                            conn.client_stream.Write(conn.host_buf_ary, 0, len);    //we want this to block
                        }
                        catch (Exception e_c)
                        {
                            if (!Handle_Disposed(e_c, conn))
                                throw;
                        }

                        conn.host_stream.BeginRead(conn.host_buf_ary, 0, Buffer_Size, Host_Write, conn);
                    }
                }
                catch (Exception e_h)
                {
                    if (!Handle_Disposed(e_h, conn))
                        throw;
                }
            }
        }

        private void Close(Connection conn)
        {
            lock (conn)
            {
                try
                {
                    if (conn.host_connected)
                        conn.host_socket.Close();
                }
                catch { }
                try
                {
                    conn.client_tcp.Close();
                }
                catch { }
            }
        }

        private bool Handle_Disposed(Exception exp,Connection conn)
        {
            if (exp is ObjectDisposedException || (exp.InnerException != null && exp.InnerException is ObjectDisposedException))
            {
                Close(conn);
                return true;
            }
            else
                return false;
        }

        private string ReadLine(MemoryStream str,Encoding encoding)    // Reads a line terminated by \r\n else returns resets postion and returns null
        {
            long idxA= str.Position;    //first position of line
            long idxB =-1;  //position after last char

            int b_last = str.ReadByte();
            int b_this = 0;

            for (long i = 1; i < str.Length; i++)
            {
                b_this = str.ReadByte();

                if (b_this == '\n' && b_last == '\r')
                {
                    idxB = str.Position;
                    str.Position = idxA;

                    int len = (int)(idxB - idxA);
                    byte[] buf = new byte[len];
                    str.Read(buf, 0, len);

                    return encoding.GetString(buf);
                }
                else
                    b_last = b_this;
            }

            str.Position = idxA;
            return null;
        }
    }
}

示例用法:

static void Main(string[] args)
{
    IPAddress localhost = IPAddress.Parse("127.0.0.1");

    IPEndPoint src_http = new IPEndPoint(localhost, 9091);
    IPEndPoint des_tor = new IPEndPoint(localhost, 9050);

    HttpOverSocksProxy proxy = new HttpOverSocksProxy(src_http, des_tor, ProxyTypes.Socks5);
    proxy.Start();

    WebClientExt client = new WebClientExt();
    client.Proxy = new WebProxy(src_http.ToString(), false);
    string res = client.DownloadString("http://en.wikipedia.org/wiki/HTTP_compression");

    Console.WriteLine(res);

    Console.WriteLine("Done");
    Console.ReadKey();
}

我必须对类 ProxySocket 进行一些小修改,以便异步调用重新调整我的状态对象。不知道为什么它还没有。

由于字符限制,我无法发布更新的代码,但我可以足够快地描述它们: 在 ProxySocket.BeginConnect 中设置 this.State = state 在 ProxySocket.OnHandShakeComplete 中设置 AsyncResult.AsyncState = State。属性 IAsyncProxyResult.AsyncState 已更新,因此有一个具有隐私“内部”的设置器

于 2014-01-25T05:01:48.253 回答