C# TcpClient.Connect 通过代理

标签 c# tcpclient proxies

我到处搜索试图弄清楚这一点,但到目前为止我所看到的一切,人们只是告诉我使用其他方法。

除此之外,我的问题是我正在尝试使用 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。

当然有一些第三方实现(google 知道的更多),但也很容易实现(部分)RFC 1928自己。

这是我刚刚一起破解的 Socks5 客户端示例。您真的很想清理它:p。只是进行身份验证协商、连接设置和最后一个简单的 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;
                }
              }
            }
          }
        }
      }
    }
  }
}

关于C# TcpClient.Connect 通过代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18289418/

相关文章:

c# - 透明窗口上的wpf webbrowser

c# - 在大文本上使用 RegEx 的最佳方式

c# - Microsoft Teams azure botframework 图标

c# - Linq - 带点符号的左外连接

c# - 读取 TcpClient 实例上的 Connected 属性时出现异常

c# - 使用 TcpClient 向服务器发送请求

C# - 为什么 StreamReader ReadLine 在调用 ReadLine 之前读取数据?

vb.net - WebBrowser 控件无法与文本文件中的代理一起使用

networking - 一台机器可以从多个不同的IP地址发出请求吗?

java - 删除 Hibernate 生成的延迟初始化代理的最安全方法是什么?