Dotnet
C#实现基础内网穿透服务的分步骤解决方案:
1. 创建控制台项目
2. 服务端代码(部署在公网服务器):
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class Server
{
private TcpListener _controlListener;
private TcpListener _publicListener;
private TcpClient _clientBridge;
public void Start(int controlPort, int publicPort)
{
_controlListener = new TcpListener(IPAddress.Any, controlPort);
_publicListener = new TcpListener(IPAddress.Any, publicPort);
_controlListener.Start();
_publicListener.Start();
// 客户端连接线程
new Thread(() => {
while(true)
{
var client = _controlListener.AcceptTcpClient();
new Thread(() => HandleClient(client)).Start();
}
}).Start();
// 公网请求处理线程
new Thread(() => {
while(true)
{
var publicClient = _publicListener.AcceptTcpClient();
if(_clientBridge != null)
{
BridgeConnections(publicClient, _clientBridge);
}
}
}).Start();
}
private void HandleClient(TcpClient client)
{
_clientBridge = client;
// 保持连接心跳
while(client.Connected)
{
Thread.Sleep(1000);
}
_clientBridge = null;
}
private void BridgeConnections(TcpClient src, TcpClient dst)
{
new Thread(() => ForwardData(src.GetStream(), dst.GetStream())).Start();
new Thread(() => ForwardData(dst.GetStream(), src.GetStream())).Start();
}
private void ForwardData(NetworkStream src, NetworkStream dst)
{
byte[] buffer = new byte[4096];
while(true)
{
int bytesRead = src.Read(buffer, 0, buffer.Length);
dst.Write(buffer, 0, bytesRead);
}
}
}
3. 客户端代码(运行在内网机器):
using System;
using System.Net.Sockets;
using System.Threading;
public class Client
{
public void Connect(string serverIp, int controlPort, string targetIp, int targetPort)
{
var client = new TcpClient();
client.Connect(serverIp, controlPort);
while(true)
{
if(client.GetStream().DataAvailable)
{
HandleServerRequest(client, targetIp, targetPort);
}
Thread.Sleep(100);
}
}
private void HandleServerRequest(TcpClient serverClient, string targetIp, int targetPort)
{
var targetClient = new TcpClient();
targetClient.Connect(targetIp, targetPort);
BridgeConnections(serverClient, targetClient);
}
private void BridgeConnections(TcpClient src, TcpClient dst)
{
new Thread(() => ForwardData(src.GetStream(), dst.GetStream())).Start();
new Thread(() => ForwardData(dst.GetStream(), src.GetStream())).Start();
}
private void ForwardData(NetworkStream src, NetworkStream dst)
{
byte[] buffer = new byte[4096];
while(true)
{
int bytesRead = src.Read(buffer, 0, buffer.Length);
dst.Write(buffer, 0, bytesRead);
}
}
}
4. 使用方式:
服务端启动:
new Server().Start(8888, 8080); // 控制端口8888,公网端口8080
客户端连接:
new Client().Connect("公网IP", 8888, "127.0.0.1", 80); // 映射本地80端口
5. 注意事项:
- 需要配置服务器防火墙放行端口
- 支持TCP协议穿透
- 基础版本不含身份验证
- 需要保持客户端持续运行
- 实际使用需添加异常处理
该实现通过端口映射建立双向隧道,服务端监听两个端口分别处理客户端连接和公网请求,客户端负责建立到内网服务的连接。数据通过流复制实现双向转发。