工具 | 协议支持 | 跨平台 | 开源性 | 学习成本 |
---|---|---|---|---|
NSmartProxy | ★★★★★ | ★★★★★ | 是 | ★★☆☆☆ |
FRP | ★★★★☆ | ★★★★★ | 是 | ★★★☆☆ |
ngrok | ★★★☆☆ | ★★★★☆ | 是 | ★★☆☆☆ |
[客户端] <---加密隧道---> [服务端] <---加密隧道---> [外部访问]
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using NSmartProxy.Core;
namespace NSmartProxy.Server
{
public class ServerHost
{
private TcpListener _server;
private readonly int _port;
private readonly int _maxConnections = 100; // 最大并发连接数
public ServerHost(int port)
{
_port = port;
}
public async Task Start()
{
_server = new TcpListener(IPAddress.Any, _port);
_server.Start(_maxConnections);
Console.WriteLine($"服务端已启动,监听端口: {_port}");
while (true)
{
// 异步等待客户端连接
var client = await _server.AcceptTcpClientAsync().ConfigureAwait(false);
_ = Task.Run(() => HandleClient(client)); // 启动独立线程处理连接
}
}
private async Task HandleClient(TcpClient client)
{
try
{
// 获取客户端IP地址
var remoteEP = client.Client.RemoteEndPoint as IPEndPoint;
Console.WriteLine($"新连接: {remoteEP.Address}:{remoteEP.Port}");
// 创建双向数据流管道
var pipe = new ConnectionPipe(client);
await pipe.StartPipeAsync().ConfigureAwait(false); // 启动数据管道
}
catch (Exception ex)
{
Console.WriteLine($"处理客户端异常: {ex.Message}");
}
finally
{
client.Close();
}
}
}
}
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace NSmartProxy.Client
{
public class Client
{
private TcpClient _client;
private string _serverIP;
private int _serverPort;
public Client(string serverIP, int serverPort)
{
_serverIP = serverIP;
_serverPort = serverPort;
}
public async Task Connect()
{
_client = new TcpClient();
await _client.ConnectAsync(_serverIP, _serverPort).ConfigureAwait(false);
Console.WriteLine($"已连接到服务端 {_serverIP}:{_serverPort}");
// 发送本地服务映射配置
var config = new ClientConfig
{
LocalPort = 8080, // 本地服务端口
RemotePath = "/api", // 外网访问路径
Protocol = ProtocolType.TCP
};
await SendConfigAsync(config).ConfigureAwait(false);
// 启动数据监听
await StartDataListen().ConfigureAwait(false);
}
private async Task SendConfigAsync(ClientConfig config)
{
// 序列化配置并发送
var configBytes = ConfigSerializer.Serialize(config);
await _client.GetStream().WriteAsync(configBytes, 0, configBytes.Length);
}
private async Task StartDataListen()
{
var networkStream = _client.GetStream();
var buffer = new byte[4096];
while (true)
{
var bytesRead = await networkStream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break; // 连接断开
// 转发数据到本地服务
await ForwardDataToLocal(buffer, bytesRead);
}
}
private async Task ForwardDataToLocal(byte[] data, int length)
{
// 连接本地服务(假设本地服务在127.0.0.1:8080)
using var localClient = new TcpClient("127.0.0.1", 8080);
await localClient.GetStream().WriteAsync(data, 0, length);
// 获取本地响应并返回
var response = new byte[4096];
var responseLength = await localClient.GetStream().ReadAsync(response);
await _client.GetStream().WriteAsync(response, 0, responseLength);
}
}
}
# 下载NSmartProxy服务端
git clone https://github.com/tmoonlight/NSmartProxy.git
# 进入服务端目录
cd NSmartProxy/Server
# 启动服务端(默认端口8080)
dotnet run --project NSmartProxy.ServerHost.csproj
// 修改客户端配置文件(ClientConfig.json)
{
"ServerIP": "your_public_ip",
"ServerPort": 8080,
"Mappings": [
{
"LocalPort": 8080, // 本地Web服务端口
"RemotePath": "/myapp", // 外网访问路径
"Protocol": "TCP"
}
]
}
// 启动客户端
dotnet run --project NSmartProxy.Client.csproj
# 通过公网IP访问
curl http://your_public_ip:8080/myapp
// 使用异步流处理(NSmartProxy.Core)
public class ConnectionPipe
{
private readonly NetworkStream _clientStream;
private readonly NetworkStream _serverStream;
public async Task StartPipeAsync()
{
// 同时处理双向数据流
_ = PipeData(_clientStream, _serverStream);
_ = PipeData(_serverStream, _clientStream);
await Task.WhenAll(
_clientStream.CopyToAsync(_serverStream),
_serverStream.CopyToAsync(_clientStream)
);
}
private async Task PipeData(NetworkStream input, NetworkStream output)
{
var buffer = new byte[8192]; // 增大缓冲区提升吞吐量
while (true)
{
var bytesRead = await input.ReadAsync(buffer);
if (bytesRead == 0) break;
await output.WriteAsync(buffer, 0, bytesRead);
}
}
}
// TLS加密配置(NSmartProxy.Server)
public class SecureServerHost : ServerHost
{
public SecureServerHost(int port, X509Certificate2 certificate)
: base(port)
{
_server = new TcpListener(new IPEndPoint(IPAddress.Any, port));
_server.Start();
_certificate = certificate; // 加载SSL证书
}
protected override async Task HandleClient(TcpClient client)
{
// 启动TLS加密
var sslStream = new SslStream(client.GetStream(), false);
await sslStream.AuthenticateAsServerAsync(_certificate);
// 继承父类逻辑
await base.HandleClient(client);
}
}
// UDP客户端实现(NSmartProxy.UdpClient)
public class UdpClientHandler
{
private readonly IPEndPoint _remoteEP;
private readonly UdpClient _udpClient;
public UdpClientHandler(string serverIP, int serverPort)
{
_remoteEP = new IPEndPoint(IPAddress.Parse(serverIP), serverPort);
_udpClient = new UdpClient();
}
public async Task Start()
{
// 绑定本地UDP端口
_udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 5000));
while (true)
{
var receiveResult = await _udpClient.ReceiveAsync();
var data = receiveResult.Buffer;
// 转发到服务端
await _udpClient.SendAsync(data, data.Length, _remoteEP);
// 接收服务端响应
var response = await _udpClient.ReceiveAsync();
// 处理响应数据...
}
}
}
// 网络诊断工具(NSmartProxy.Utils)
public static class NetworkDiagnostic
{
public static async Task CheckConnection(string serverIP, int port)
{
try
{
using var client = new TcpClient();
await client.ConnectAsync(serverIP, port);
Console.WriteLine("连接成功");
}
catch (Exception ex)
{
Console.WriteLine($"连接失败: {ex.Message}");
}
}
}
// 使用连接池复用(NSmartProxy.Core)
public class ConnectionPool
{
private readonly ConcurrentBag<TcpClient> _pool = new();
public TcpClient GetClient(string serverIP, int port)
{
if (_pool.TryTake(out var client))
{
return client;
}
return new TcpClient(serverIP, port);
}
public void ReturnClient(TcpClient client)
{
_pool.Add(client);
}
}
通过本文的深度实践,开发者可以掌握: