C#TCP客户端。通过代理连接

C#TCP客户端。通过代理连接,c#,tcpclient,proxies,C#,Tcpclient,Proxies,我到处寻找,试图弄明白这一点,但到目前为止,我所看到的一切,人们只是告诉我使用其他方法 这样一来,我的问题是我正试图使用socks 5代理通过TcpClient连接到服务器 我当前的设置是: Client = new TcpClient(); Client.Connect(EndPoint); NetworkStream = Client.GetStream(); Stream = new new BufferedStream(Ne

我到处寻找,试图弄明白这一点,但到目前为止,我所看到的一切,人们只是告诉我使用其他方法

这样一来,我的问题是我正试图使用socks 5代理通过TcpClient连接到服务器

我当前的设置是:

        Client = new TcpClient();
        Client.Connect(EndPoint);
        NetworkStream = Client.GetStream();
        Stream = new new BufferedStream(NetworkStream);
        Stream.Write...//Write Packet information etc

我不确定是否遗漏了任何信息,因此如果遗漏了,我会很高兴地更新此信息。

我真的不认为.Net配备了Socks5支持或代理TCP

当然,有两种第三方实现(谷歌知道更多),但也很容易自己实现(部分)

这里有一个我刚刚拼凑的Socks5客户端的例子。你会很想把它清理干净的。只需进行身份验证协商、连接设置,最后是一个简单的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;
                }
              }
            }
          }
        }
      }
    }
  }
}
使用系统;
使用System.IO;
Net系统;
使用System.Net.Sockets;
使用系统文本;
命名空间tcpsocks5
{
静态类程序
{
静态void ReadAll(此网络流,字节[]缓冲区,int偏移量,int大小)
{
while(大小!=0){
var read=stream.read(缓冲区、偏移量、大小);
如果(读取<0){
抛出新IOException(“过早结束”);
}
大小-=读取;
偏移量+=读取;
}
}
静态void Main(字符串[]参数)
{
使用(var client=new TcpClient()){
client.Connect(ip,端口);//自己提供ip,端口
使用(var stream=client.GetStream()){
//认证
var buf=新字节[300];
buf[0]=0x05;//版本
buf[1]=0x01;//n方法
buf[2]=0x00;//没有身份验证方法
stream.Write(buf,0,3);
ReadAll(buf,0,2);
如果(buf[0]!=0x05){
抛出新IOException(“无效Socks版本”);
}
if(buf[1]==0xff){
抛出新IOException(“Socks服务器不支持无身份验证”);
}
如果(buf[1]!=0x00){
抛出新异常(“Socks服务器确实选择了伪身份验证”);
}
//请求
buf[0]=0x05;//版本
buf[1]=0x01;//连接(TCP)
buf[2]=0x00;//保留
buf[3]=0x03;//目的地地址:域名
var domain=Encoding.ASCII.GetBytes(“google.com”);
buf[4]=(字节)domain.Length;//域名长度(八位字节)
数组.Copy(域,0,buf,5,域.Length);
var port=BitConverter.GetBytes(
IPAddress.HostToNetworkOrder((短)80));
buf[5+域.长度]=端口[0];
buf[6+域长度]=端口[1];
stream.Write(buf,0,domain.Length+7);
//答复:
ReadAll(buf,0,4);
如果(buf[0]!=0x05){
抛出新IOException(“无效Socks版本”);
}
如果(buf[1]!=0x00){
抛出新的IOException(string.Format(“Socks错误{0:X}”,buf[1]);
}
var rdest=string.Empty;
开关(buf[3]){
案例0x01://IPv4
ReadAll(buf,0,4);
var v4=位转换器.ToUInt32(buf,0);
rdest=新的IPAddress(v4).ToString();
打破
案例0x03://域名
ReadAll(buf,0,1);
if(buf[0]==0xff){
抛出新IOException(“无效域名”);
}
ReadAll(buf,1,buf[0]);
rdest=Encoding.ASCII.GetString(buf,1,buf[0]);
打破
案例0x04://IPv6
var八位字节=新字节[16];
ReadAll(八位字节,0,16);
rdest=新的IP地址(八位字节).ToString();
打破
违约:
抛出新IOException(“无效地址类型”);
}
ReadAll(buf,0,2);
var rport=(ushort)IPAddress.NetworkToHostOrder((短)BitConverter.ToUInt16(buf,0));
WriteLine(“通过{0}:{1}连接”,rdest,rport);
//发出HTTP请求,又名“做一些事情…”
使用(var writer=新的StreamWriter(流)){
Write(“GET/HTTP/1.1\r\nHost:google.com\r\n\r\n”);
writer.Flush();
使用(变量读取器=新的流读取器(流)){
while(true){
var line=reader.ReadLine();
if(string.IsNullOrEmpty(行)){
打破
}
}
}
}
}
}
}
}
}
我使用。它是免费的,开源的

在下面的示例中,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();