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;
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM