C# TcpClient.Подключение через прокси
Я искал повсюду, пытаясь понять это, но все, что я видел до сих пор, люди просто говорят мне использовать другие методы.
С этим из пути, моя проблема в том, что я пытаюсь подключиться к серверу через TcpClient, используя прокси-сервер socks 5
моя текущая настройка:
Client = new TcpClient();
Client.Connect(EndPoint);
NetworkStream = Client.GetStream();
Stream = new new BufferedStream(NetworkStream);
Stream.Write...//Write Packet information etc
Я не уверен, что пропустил какую-либо информацию, поэтому, если у меня есть, я с удовольствием обновлю это.
2 ответов
Я действительно не думаю, что .Net оснащен поддержкой Socks5 или проксированным TCP.
есть несколько сторонних реализаций (google знает больше), конечно, но это также довольно легко реализовать (часть) RFC 1928 себя.
вот пример клиента Socks5, который я только что взломал. Вы действительно захотите очистить его: p. Просто выполняет согласование auth, настройку соединения и, наконец, простой http-запрос.
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace tcpsocks5
{
static class Program
{
static void ReadAll(this NetworkStream stream, byte[] buffer, int offset, int size)
{
while (size != 0) {
var read = stream.Read(buffer, offset, size);
if (read < 0) {
throw new IOException("Premature end");
}
size -= read;
offset += read;
}
}
static void Main(string[] args)
{
using (var client = new TcpClient()) {
client.Connect(ip, port); // Provide IP, Port yourself
using (var stream = client.GetStream()) {
// Auth
var buf = new byte[300];
buf[0] = 0x05; // Version
buf[1] = 0x01; // NMETHODS
buf[2] = 0x00; // No auth-method
stream.Write(buf, 0, 3);
stream.ReadAll(buf, 0, 2);
if (buf[0] != 0x05) {
throw new IOException("Invalid Socks Version");
}
if (buf[1] == 0xff) {
throw new IOException("Socks Server does not support no-auth");
}
if (buf[1] != 0x00) {
throw new Exception("Socks Server did choose bogus auth");
}
// Request
buf[0] = 0x05; // Version
buf[1] = 0x01; // Connect (TCP)
buf[2] = 0x00; // Reserved
buf[3] = 0x03; // Dest.Addr: Domain name
var domain = Encoding.ASCII.GetBytes("google.com");
buf[4] = (byte)domain.Length; // Domain name length (octet)
Array.Copy(domain, 0, buf, 5, domain.Length);
var port = BitConverter.GetBytes(
IPAddress.HostToNetworkOrder((short)80));
buf[5 + domain.Length] = port[0];
buf[6 + domain.Length] = port[1];
stream.Write(buf, 0, domain.Length + 7);
// Reply
stream.ReadAll(buf, 0, 4);
if (buf[0] != 0x05) {
throw new IOException("Invalid Socks Version");
}
if (buf[1] != 0x00) {
throw new IOException(string.Format("Socks Error {0:X}", buf[1]));
}
var rdest = string.Empty;
switch (buf[3]) {
case 0x01: // IPv4
stream.ReadAll(buf, 0, 4);
var v4 = BitConverter.ToUInt32(buf, 0);
rdest = new IPAddress(v4).ToString();
break;
case 0x03: // Domain name
stream.ReadAll(buf, 0, 1);
if (buf[0] == 0xff) {
throw new IOException("Invalid Domain Name");
}
stream.ReadAll(buf, 1, buf[0]);
rdest = Encoding.ASCII.GetString(buf, 1, buf[0]);
break;
case 0x04: // IPv6
var octets = new byte[16];
stream.ReadAll(octets, 0, 16);
rdest = new IPAddress(octets).ToString();
break;
default:
throw new IOException("Invalid Address type");
}
stream.ReadAll(buf, 0, 2);
var rport = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(buf, 0));
Console.WriteLine("Connected via {0}:{1}", rdest, rport);
// Make an HTTP request, aka. "do stuff ..."
using (var writer = new StreamWriter(stream)) {
writer.Write("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n");
writer.Flush();
using (var reader = new StreamReader(stream)) {
while (true) {
var line = reader.ReadLine();
if (string.IsNullOrEmpty(line)) {
break;
}
}
}
}
}
}
}
}
}
Я использую starksoft-Аспен. Это бесплатно и с открытым исходным кодом.
в примере ниже TcpClient инициализируется в методе" CreateConnection ()", но вы также можете инициализировать клиент самостоятельно, а также сделать все это асинхронно.
using Starksoft.Aspen.Proxy;
Socks5ProxyClient proxyClient = new Socks5ProxyClient(
socks5Proxy.Host, socks5Proxy.Port,
socks5Proxy.Username, socks5Proxy.Password);
TcpClient client = proxyClient.CreateConnection(destination.Host,
destination.Port);
NetworkStream stream = client.GetStream();