程序员开发实例大全宝库

网站首页 > 编程文章 正文

使用C#写一个最最简单的数据流端口转发小工具

zazugpt 2024-08-13 13:19:26 编程文章 31 ℃ 0 评论


一、端口转发功能是一种网络工具,用于将来自一个网络端口的流量重定向到另一个网络端口。它有许多用途,包括但不限于以下几个方面:

  1. 内部网络穿透(Internal Network Penetration):在内部网络环境中,可以使用端口转发来访问内部服务器或服务,即使这些服务器或服务只能在内部网络中访问。
  2. 远程访问内部资源:通过在防火墙后设置端口转发,可以远程访问公司内部资源,比如数据库、文件共享或者内部网站等,从而实现远程办公或者远程维护。
  3. 隐藏真实服务:可以将真实服务隐藏在不常用的端口上,然后通过端口转发将外部请求重定向到这些端口。这样可以增加安全性,降低暴露真实服务的风险。
  4. 虚拟主机:在共享主机上,可以使用端口转发来实现虚拟主机功能,使得多个网站可以共享同一个 IP 地址和端口,但通过不同的域名访问。
  5. 负载均衡:可以使用端口转发来实现负载均衡,将流量分发到多个后端服务器上,提高整体系统的性能和可靠性。
  6. 端口映射:用于将一个端口的流量映射到另一个端口,这在一些特定的网络配置下是很有用的,比如在 NAT(Network Address Translation)环境中。

二、端口转发功能可以通过多种现成的工具软件来实现,其中一些是专门设计用于端口转发的工具,而另一些则是通用的网络工具,也可以用于端口转发。以下是一些常见的工具软件:

  1. Ngrok: Ngrok 是一个广泛使用的工具,可以将本地服务暴露到公共 Internet 上,支持 TCP 和 HTTP 协议的端口转发。它提供了简单易用的命令行界面,并且支持多平台使用。
  2. SSH: SSH(Secure Shell)是一个安全的远程登录协议,也可以用于端口转发。通过 SSH 客户端和服务器,可以将本地端口转发到远程主机上,或者将远程端口转发到本地主机上。
  3. socat: socat 是一个功能强大的网络工具,可以用于在不同的网络接口、文件、管道之间建立连接。它支持多种协议,可以实现 TCP、UDP 等各种类型的端口转发。
  4. Haproxy: Haproxy 是一个高性能的负载均衡器和反向代理服务器,也可以用于端口转发。它支持 TCP 和 HTTP 协议的转发,并提供了丰富的配置选项和灵活的部署方式。
  5. Fiddler: Fiddler 是一个强大的 Web 调试工具,也可以用于端口转发。它支持 HTTP 和 HTTPS 协议的转发,并提供了丰富的功能和插件生态系统。
  6. Zerotier: Zerotier 是一个简单易用的软件定义的广域网(SD-WAN)工具,可以将多个设备连接到一个虚拟的私有网络中,支持 UDP 和 TCP 协议的端口转发。
  7. Ncat: Ncat 是 Nmap 项目中的一个工具,是一个强大的网络工具箱,可以用于端口扫描、连接、转发等多种网络任务。

三、看了上面那么多软件,经过一番研究,下面我使用C#实现一个很简单的端口转发类,希望能给大家起到一个举一反三的作用。代码如下:

    public class PortRelay
    {
        /// <summary>
        /// 缓冲区大小
        /// </summary>
        private const int BufferSize = 8192;
        /// <summary>
        /// 本机源商品
        /// </summary>
        private readonly int _sourcePort;
        /// <summary>
        /// 目标电脑端口
        /// </summary>
        private readonly int _destinationPort;
        /// <summary>
        /// 目标电脑IP
        /// </summary>
        private readonly IPAddress _destinationIP;
        /// <summary>
        /// 超时时间
        /// </summary>
        private readonly int _timeoutMilliseconds;
        /// <summary>
        /// 关闭标识
        /// </summary>
        private CancellationTokenSource cancellationTokenSource;
        /// <summary>
        /// 监听器
        /// </summary>
        private TcpListener sourceListener;
        /// <summary>
        /// 端口转发
        /// </summary>
        /// <param name="sourcePort">本机端口</param>
        /// <param name="destinationIP">目标IP</param>
        /// <param name="destinationPort">目标端口</param>
        /// <param name="timeoutMilliseconds">超时时间(毫秒)</param>
        public PortRelay(int sourcePort, IPAddress destinationIP, int destinationPort, int timeoutMilliseconds)
        {
            _sourcePort = sourcePort;
            _destinationIP = destinationIP;
            _destinationPort = destinationPort;
            _timeoutMilliseconds = timeoutMilliseconds;
        }
        /// <summary>
        /// 启动端口转发
        /// </summary>
        /// <returns></returns>
        public async Task StartForwardingAsync()
        {
            //取消标识
            cancellationTokenSource = new CancellationTokenSource();
            //开始监听端口
            sourceListener = new TcpListener(IPAddress.Any, _sourcePort);
            //开始监听
            sourceListener.Start();
            try
            {
                //如果没有取消
                while (!cancellationTokenSource.IsCancellationRequested)
                {
                    //接收一个新的客户端
                    var client = await sourceListener.AcceptTcpClientAsync();
                    if (client != null)
                    {
                        Console.WriteLine(#34;新的客户端连接:{client.Client.RemoteEndPoint.ToString()}");
                        //开始转发数据包
                        _ = Task.Run(() => ForwardDataAsync(client, cancellationTokenSource.Token));
                    }
                }
            }
            catch(Exception ex)
            {//写日志
            }
            finally
            {
                sourceListener.Stop();
            }
        }

        /// <summary>
        /// 转发数据包
        /// </summary>
        /// <param name="client"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task ForwardDataAsync(TcpClient client, CancellationToken cancellationToken)
        {
            using (client)
            {
                //连接目标电脑IP与端口
                var destinationClient = new TcpClient();
                //异步连接
                var connectTask = destinationClient.ConnectAsync(_destinationIP, _destinationPort);
                if (await Task.WhenAny(connectTask, Task.Delay(_timeoutMilliseconds, cancellationToken)) != connectTask)
                {
                    // Timeout occurred
                    Console.WriteLine("连接超时");
                    return;
                }
                //开始转发
                using (destinationClient)
                {
                    using (var sourceStream = client.GetStream())
                    {
                        using (var destinationStream = destinationClient.GetStream())
                        {
                            await Task.WhenAny(
                                sourceStream.CopyToAsync(destinationStream, BufferSize, cancellationToken),
                                destinationStream.CopyToAsync(sourceStream, BufferSize, cancellationToken)
                            );
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 关闭
        /// </summary>
        /// <returns></returns>
        public async Task CloseAsync()
        {
           await Task.Run(() =>
            {
                this.cancellationTokenSource.Cancel();
            });
        }
    }

使用方法如下:

   PortRelay portRelay = new PortRelay(9999, IPAddress.Parse("127.0.0.1"), 8080, 5000);
   await portRelay.StartForwardingAsync();

上面意思是监听本机9999端口,将数据转发到目标IP(127.0.0.1)的8080商品,连接超时为5秒钟。这段代码供您参考!


文章如果对您有用,点个赞吧!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表