我正在尝试使用带有Stacksoft.net库的socks 5协议来获取页面:
ProxyClientFactory cf = new ProxyClientFactory();
var p = cf.CreateProxyClient(ProxyType.Socks5, "127.0.0.1", 9051, "", "");
var c = p.CreateConnection("www.google.com",80);
当我运行此操作时,我遇到以下异常:
Unable to read data from the transport connection: An established connection was aborted by the software in your host machine.
Inner exception:An established connection was aborted by the software in your host machine
当程序尝试从google.com stream.Read(response, 0, response.Length);
读取响应时抛出异常:
private void SendCommand(byte command, string destinationHost, int destinationPort)
{
NetworkStream stream = _tcpClient.GetStream();
byte addressType = GetDestAddressType(destinationHost);
byte[] destAddr = GetDestAddressBytes(addressType, destinationHost);
byte[] destPort = GetDestPortBytes(destinationPort);
// The connection request is made up of 6 bytes plus the
// length of the variable address byte array
//
// +----+-----+-------+------+----------+----------+
// |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
// +----+-----+-------+------+----------+----------+
// | 1 | 1 | X'00' | 1 | Variable | 2 |
// +----+-----+-------+------+----------+----------+
//
// * VER protocol version: X'05'
// * CMD
// * CONNECT X'01'
// * BIND X'02'
// * UDP ASSOCIATE X'03'
// * RSV RESERVED
// * ATYP address itemType of following address
// * IP V4 address: X'01'
// * DOMAINNAME: X'03'
// * IP V6 address: X'04'
// * DST.ADDR desired destination address
// * DST.PORT desired destination port in network octet order
byte[] request = new byte[4 + destAddr.Length + 2];
request[0] = SOCKS5_VERSION_NUMBER;
request[1] = command;
request[2] = SOCKS5_RESERVED;
request[3] = addressType;
destAddr.CopyTo(request, 4);
destPort.CopyTo(request, 4 + destAddr.Length);
// send connect request.
stream.Write(request, 0, request.Length);
// PROXY SERVER RESPONSE
// +----+-----+-------+------+----------+----------+
// |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
// +----+-----+-------+------+----------+----------+
// | 1 | 1 | X'00' | 1 | Variable | 2 |
// +----+-----+-------+------+----------+----------+
//
// * VER protocol version: X'05'
// * REP Reply field:
// * X'00' succeeded
// * X'01' general SOCKS server failure
// * X'02' connection not allowed by ruleset
// * X'03' Network unreachable
// * X'04' Host unreachable
// * X'05' Connection refused
// * X'06' TTL expired
// * X'07' Command not supported
// * X'08' Address itemType not supported
// * X'09' to X'FF' unassigned
//* RSV RESERVED
//* ATYP address itemType of following address
byte[] response = new byte[255];
// read proxy server response
stream.Read(response, 0, response.Length);
我做错了什么?
答案 0 :(得分:2)
抱歉延迟回复,我已经找到了这个小型的“库”,它基本上暴露了一个单例Tor类和一个socks类;这是一个大项目的一部分,我不想拖延我的答案。我希望我的方法为你提供一些方向。
我只想注意,我在测试时遇到的唯一问题是我似乎没有获得完整的http返回有效负载,这意味着代理类似乎只从Web服务器捕获一部分html代码。我相信这是由于Tor网络所涉及的大延迟。我试图增加缓冲阵列的大小,但没有帮助。如果你想出一个解决方案,我将非常感激
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Starksoft.Net.Proxy;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Web;
using System.Threading;
namespace networking
{
namespace client
{
internal class proxy
{
public struct conn
{
internal TcpClient http;
internal IProxyClient Proxy;
public ProxyType proxy_type;
public string proxy_host;
public int proxy_port;
public string target_host;
public int target_port;
public string recv_packet;
public void proxy_config(string target_host, int target_port, string proxy_host, int proxy_port, ProxyType type)
{
this.target_host = target_host; this.target_port = target_port;
this.proxy_host = proxy_host; this.proxy_port = proxy_port;
this.proxy_type = type;
}
}
public conn proxy_conn;
internal proxy(string target_host, int target_port, string proxy_host, int proxy_port, ProxyType type)
{
Console.WriteLine("Socket allocated.");
this.proxy_conn = new proxy.conn();
this.proxy_conn.proxy_config(target_host, target_port, proxy_host, proxy_port, type);
ProxyClientFactory factory = new ProxyClientFactory();
this.proxy_conn.Proxy = factory.CreateProxyClient(type, proxy_host, proxy_port);
this.proxy_conn.Proxy.CreateConnectionAsyncCompleted += new EventHandler<CreateConnectionAsyncCompletedEventArgs>(proxy_connected);
//this.Proxy.CreateConnectionAsync(obj.target_host, obj.target_port);
}
internal void connect()
{
this.proxy_conn.Proxy.CreateConnectionAsync(this.proxy_conn.target_host, this.proxy_conn.target_port);
}
private void proxy_connected(object sender, CreateConnectionAsyncCompletedEventArgs e)
{
if (e.Error != null)
{
Console.WriteLine("Connection Error!");
Console.WriteLine(e.Error.Message);
return;
}
else if (e.Error == null)
{
// get a reference to the open proxy connection
Console.WriteLine("Connected to Tor!");
this.proxy_conn.http = e.ProxyConnection;
Console.WriteLine("Proxy referenced.");
}
}
public void send(string data)
{
this.proxy_conn.http.Client.Send(ASCIIEncoding.ASCII.GetBytes(data));
}
public string recv()
{
byte[] rcvBuffer = new byte[1024]; //1024
int bytes = this.proxy_conn.http.Client.Receive(rcvBuffer, 1024, SocketFlags.None);
this.proxy_conn.recv_packet += ASCIIEncoding.ASCII.GetString(rcvBuffer, 0, bytes);
return this.proxy_conn.recv_packet;
}
}
internal class Tor
{
private static Tor instance;
private Process tor;
//private conn obj_conn;
private Tor(){}
internal static Tor Instance
{
get
{
if (instance == null)
{
instance = new Tor();
}
return instance;
}
}
internal void tor_start()
{
if (this.tor == null)
{
Console.WriteLine("Tor init...");
this.tor = new Process();
this.tor.StartInfo.FileName = "tor.exe";
this.tor.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
Console.WriteLine(Directory.GetCurrentDirectory());
this.tor.StartInfo.CreateNoWindow = false;
this.tor.StartInfo.UseShellExecute = false;
this.tor.StartInfo.RedirectStandardOutput = true;
this.tor.StartInfo.RedirectStandardInput = true;
this.tor.StartInfo.RedirectStandardError = true;
this.tor.OutputDataReceived += new DataReceivedEventHandler((sender, args) => { stdout__tor(sender, args); });
this.tor.ErrorDataReceived += new DataReceivedEventHandler((sender, args) => { stderr__tor(sender, args); });
this.tor.Start();
Console.WriteLine("Strapping input...");
this.tor.BeginOutputReadLine();
this.tor.BeginErrorReadLine();
}
else
{
Console.WriteLine("A Tor process already exists.");
}
}
internal void tor_stop()
{
this.tor.StandardOutput.Close();
this.tor.StandardInput.Close();
this.tor.StandardError.Close();
this.tor.Kill();
this.tor.Dispose();
this.tor = null;
}
internal void tor_restart()
{
tor_stop();
tor_start();
}
private void stdout__tor(object sender, DataReceivedEventArgs pipe)
{
if (pipe.Data.Contains("Bootstrapped 100%: Done."))
{
Console.WriteLine("Tor has been initialized.");
//this.obj_conn.Proxy.CreateConnectionAsync(obj_conn.target_host, obj_conn.target_port);
}
Console.WriteLine(pipe.Data);
}
private void stderr__tor(object sender, DataReceivedEventArgs pipe)
{
Console.WriteLine("[ERROR]: " + pipe.Data);
}
}
}
public class socket
{
internal static client.Tor Tor_obj;
internal static List<client.proxy> proxy_socks;
public socket()
{
if (Tor_obj == null || proxy_socks == null)
{
if (Tor_obj == null)
{
Tor_obj = client.Tor.Instance;
Tor_obj.tor_start();
}
if (proxy_socks == null)
{
proxy_socks = new List<client.proxy>();
}
}
}
public int add(string type, string host, int port)
{
int index = -1;
if (type == "proxy")
{
proxy_socks.Add(new client.proxy(host, port, "127.0.0.1", 9050, ProxyType.Socks4a));
index = proxy_socks.Count() - 1;
proxy_socks[index].connect();
return index;
}
return index;
}
}
}
namespace myprog
{
class Program
{
static void Main(string[] args)
{
networking.socket connections = new networking.socket();
Thread.Sleep(20000);
int conn_index = connections.add("proxy", "checkmyip.com", 80);
Thread.Sleep(10000);
networking.socket.proxy_socks[conn_index].send("GET / HTTP/1.1\r\nHost: checkmyip.com\r\n\r\n");
Console.WriteLine(WebUtility.HtmlDecode(networking.socket.proxy_socks[conn_index].recv()));
Thread.Sleep(50000);
}
}
}
我调用thread.sleep()以确保Tor进程已完全连接,然后建立与Tor的代理连接,并在此时发出请求。