14

我正在尝试以编程方式向 Tor 控制端口发送命令以使其刷新链。我无法在 C# 中找到任何示例,并且我的解决方案不起作用。请求超时。我的服务正在运行,我可以看到它正在侦听控制端口。

public string Refresh()
{
    TcpClient client = new TcpClient("localhost", 9051);
    string response = string.Empty;
    string authenticate = MakeTcpRequest("AUTHENTICATE\r\n", client);
    if (authenticate.Equals("250"))
    {
        response = MakeTcpRequest("SIGNAL NEWNYM\r\n", client);
    }
    client.Close();
    return response;
}

public string MakeTcpRequest(string message, TcpClient client)
{
    client.ReceiveTimeout = 20000;
    client.SendTimeout = 20000;
    string proxyResponse = string.Empty;

    try
    {
        // Send message
        StreamWriter streamWriter = new StreamWriter(client.GetStream());
        streamWriter.Write(message);
        streamWriter.Flush();

        // Read response
        StreamReader streamReader = new StreamReader(client.GetStream());
        proxyResponse = streamReader.ReadToEnd();
    }
    catch (Exception ex)
    {
        // Ignore
    }

    return proxyResponse;
}

谁能发现我做错了什么?

编辑:

按照 Hans 的建议(由于某种原因他现在已将其删除),我尝试发送“AUTHENTICATE\n”而不仅仅是“AUTHENTICATE”。现在我从 Tor 收到一个错误:“551 无效的引号字符串。您需要将密码放在双引号中。” 至少有一些进展。

然后我尝试发送“AUTHENTICATE \”\“\n”,就像它想要的那样,但它在等待响应时超时。

编辑:

该命令在 Windows Telnet 客户端中运行良好。我什至不必添加引号。无法弄清楚出了什么问题。也许双引号在发送时没有正确编码?

4

4 回答 4

8
    public static void CheckIfBlocked(ref HtmlDocument htmlDoc, string ypURL, HtmlWeb hw)
    {
        if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
        {
            Console.WriteLine("Getting Blocked");
            Utils.RefreshTor();
            htmlDoc = hw.Load(ypURL, "127.0.0.1", 8118, null, null);
            if (htmlDoc.DocumentNode.InnerText.Contains("FORBIDDEN ACCESS!"))
            {
                Console.WriteLine("Getting Blocked");
                Utils.RefreshTor();
            }
        }
    }
    public static void RefreshTor()
    {
        IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9051);
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            server.Connect(ip);
        }
        catch (SocketException e)
        {
            Console.WriteLine("Unable to connect to server.");
            RefreshTor();
            return;
        }

        server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"butt\"\n"));
        byte[] data = new byte[1024];
        int receivedDataLength = server.Receive(data);
        string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);

        if (stringData.Contains("250"))
        {
            server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM\r\n"));
            data = new byte[1024];
            receivedDataLength = server.Receive(data);
            stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
            if (!stringData.Contains("250"))
            {
                Console.WriteLine("Unable to signal new user to server.");
                server.Shutdown(SocketShutdown.Both);
                server.Close();
                RefreshTor();
            }
        }
        else
        {
            Console.WriteLine("Unable to authenticate to server.");
            server.Shutdown(SocketShutdown.Both);
            server.Close();
            RefreshTor();
        }
        server.Shutdown(SocketShutdown.Both);
        server.Close();
    }
于 2011-08-25T14:53:00.557 回答
4

当我发送 AUTHENTICATE 命令时,StreamReader 正在读取结束的响应,但没有结束,因为成功时流保持打开状态。所以我把它改成了在这种情况下只读取响应的第一行。

public static string MakeTcpRequest(string message, TcpClient client, bool readToEnd)
{
    client.ReceiveTimeout = 20000;
    client.SendTimeout = 20000;
    string proxyResponse = string.Empty;

    try
    {
        // Send message
        using (StreamWriter streamWriter = new StreamWriter(client.GetStream()))
        {
            streamWriter.Write(message);
            streamWriter.Flush();
        }

        // Read response
        using (StreamReader streamReader = new StreamReader(client.GetStream()))
        {
            proxyResponse = readToEnd ? streamReader.ReadToEnd() : streamReader.ReadLine();
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }

    return proxyResponse;
}
于 2010-05-05T10:17:09.187 回答
1
于 2015-10-01T06:21:45.147 回答
0

可能您使用的是为控制端口访问生成散列密码的 Vidalia。您需要使用 Tor 控制台应用程序并配置一个 torrc 文件。

于 2012-02-21T19:04:06.330 回答