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; } } } }
桂棹兮兰桨,击空明兮溯流光。