如何在C#中使用Tor控制协议?

Edg*_*gar 14 .net c# network-programming tcpclient tor

我正在尝试以编程方式将命令发送到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;
}
Run Code Online (Sandbox Code Playgroud)

谁能发现我做错了什么?

编辑:

根据汉斯的建议,他现在已经删除了某些原因,我试图发送"AUTHENTICATE \n"而不仅仅是"AUTHENTICATE".现在我从Tor回来了一个错误:"551无效的引用字符串.你需要把密码放在双引号中." 至少有一些进展.

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

编辑:

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

Mvc*_*Jon 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();
    }
Run Code Online (Sandbox Code Playgroud)


Edg*_*gar 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;
}
Run Code Online (Sandbox Code Playgroud)