C#端口转发

转载自:https://www.jb51.net/article/62638.htm

太优秀的示例代码,转载了

using System;
using System.Net.Sockets;
using System.Threading;
namespace PortTransponder
{
  class Program
  {
    static void Main(string[] args)
    {
      TcpListener tl = new TcpListener(80);
//这里开对方可以被你连接并且未被占用的端口
      tl.Start();
      while (true)
//这里必须用循环,可以接收不止一个客户
//因为我发现终端服务有时一个端口不行就换一个端口重连
      {
//下面的意思就是一旦程序收到你发送的数据包后立刻开2个线程做中转
        try
        {
          TcpClient tc1 = tl.AcceptTcpClient();
//这里是等待数据再执行下边,不会100%占用cpu
          TcpClient tc2 = new TcpClient("localhost", 3389);
          tc1.SendTimeout = 300000;
//设定超时,否则端口将一直被占用,即使失去连接
          tc1.ReceiveTimeout = 300000;
          tc2.SendTimeout = 300000;
          tc2.ReceiveTimeout = 300000;
          object obj1 = (object)(new TcpClient[] { tc1, tc2 });
          object obj2 = (object)(new TcpClient[] { tc2, tc1 });
          ThreadPool.QueueUserWorkItem(new WaitCallback(transfer), obj1);
          ThreadPool.QueueUserWorkItem(new WaitCallback(transfer), obj2);
        }
        catch { }
      }
    }
    public static void transfer(object obj)
    {
      TcpClient tc1 = ((TcpClient[])obj)[0];
      TcpClient tc2 = ((TcpClient[])obj)[1];
      NetworkStream ns1 = tc1.GetStream();
      NetworkStream ns2 = tc2.GetStream();
      while (true)
      {
        try
        {
//这里必须try catch,否则连接一旦中断程序就崩溃了
//要是弹出错误提示让机主看见那就囧了
          byte[] bt = new byte[10240];
          int count = ns1.Read(bt, 0, bt.Length);
          ns2.Write(bt, 0, count);
        }
        catch
        {
          ns1.Dispose();
          ns2.Dispose();
          tc1.Close();
          tc2.Close();
          break;
        }
      }
    }
  }
}

 下面是原创的socket版,不是转载的哦

class Program
{
    static bool resetFlag = true;
    static readonly object resetFlagLocker = new object();

    static void Main(string[] args)
    {
        var localSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        localSocket.Bind(new IPEndPoint(IPAddress.Any, 20000));
        localSocket.Listen(10);

        while (true)
        {
            try
            {
                lock (resetFlagLocker)
                {
                    if (!resetFlag)
                        continue;

                    resetFlag = false;
                }

                var client1 = localSocket.Accept();
                client1.SendTimeout = 300000;
                client1.ReceiveTimeout = 300000;

                var client2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client2.Connect("localhost",3389);

                object obj1 = (object)(new Socket[] { client1, client2 });
                object obj2 = (object)(new Socket[] { client2, client1 });

                ThreadPool.QueueUserWorkItem(new WaitCallback(transfer), obj1);
                ThreadPool.QueueUserWorkItem(new WaitCallback(transfer), obj2);
                
                Console.WriteLine("Transfer started");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Main error:" + ex.Message);
            }
        }
    }

    public static void transfer(object obj)
    {
        var socketA = ((Socket[])obj)[0];
        var socketB = ((Socket[])obj)[1];
        
        while (true)
        {
            try
            {
                var data = new byte[10240];
                int read = socketA.Receive(data);
                socketB.Send(data.Take(read).ToArray());
            }
            catch (Exception ex)
            {
                lock (resetFlagLocker)
                {
                    resetFlag = true;
                }

                Console.Write("Transfer error:" + ex.Message);
                
                try { socketA.Close(); } catch {}
                try { socketB.Close(); } catch {}
                
                break;
            }
        }
    }
}

 

posted on 2020-12-09 17:06  空明流光  阅读(2085)  评论(0编辑  收藏  举报

导航