TcpRouter端口转发工具
using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; namespace TcpRouter { class Program { private int listenPort; private string ip; private int port; private ConcurrentDictionary<IPEndPoint, ProxyItem> proxies = new ConcurrentDictionary<IPEndPoint, ProxyItem>(); private TcpListener listener; private log4net.ILog log; public Program( int listenPort, string ip, int port) { // TODO: Complete member initialization this .listenPort = listenPort; this .ip = ip; this .port = port; } static void Main( string [] args) { log4net.Config.XmlConfigurator.ConfigureAndWatch( new System.IO.FileInfo(System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)); Console.Write( "请输入监听端口:" ); int listenPort = int .Parse(Console.ReadLine()); Console.Write( "请输入转发目标(IP:PORT):" ); string strDest = Console.ReadLine(); string ip; int port; { string [] items = strDest.Split( ':' ); ip = items[0]; port = int .Parse(items[1]); } Console.Title = string .Format( "TCP:{0}=>{1}" , listenPort, strDest); Program p = new Program(listenPort, ip, port); p.Run(); } private void Run() { this .log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); System.AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); IPEndPoint localEP = new IPEndPoint(IPAddress.Any, this .listenPort); this .listener = new TcpListener(localEP); listener.Start(100); listener.BeginAcceptSocket(OnAccepted, listener); Console.ReadLine(); } void CurrentDomain_UnhandledException( object sender, UnhandledExceptionEventArgs e) { log.Fatal( "UnhandledException" , (Exception)e.ExceptionObject); } public void OnAccepted(IAsyncResult ar) { TcpListener listener = ar.AsyncState as TcpListener; Socket remoteSocket = listener.EndAcceptSocket(ar); listener.BeginAcceptSocket(OnAccepted, listener); Socket proxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { proxy.BeginConnect( this .ip, this .port, arConn => { try { proxy.EndConnect(arConn); this .SetupProxy( new ProxyItem() { Proxy = proxy, RemoteSocket = remoteSocket }); } catch (Exception exp) { log.Debug(exp.Message); //断开连接 //remoteSocket.BeginDisconnect(false, ardc => { // remoteSocket.EndDisconnect(ardc); //}, remoteSocket); //改为增加日志 byte [] buffer = new byte [1024]; remoteSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, arRecv => { try { int received = remoteSocket.EndReceive(arRecv); this .Print(remoteSocket.RemoteEndPoint.ToString(), "non" , buffer, 0, received); } catch (SocketException ex) { log.Debug(ex); } catch (ObjectDisposedException ex) { log.Debug(ex); } }, null ); } }, proxy); } catch (Exception exp) { log.Debug(exp); } } private void SetupTransfer(Socket src, Socket des) { string srcAddress = src.RemoteEndPoint.ToString(); string desAddress = des.RemoteEndPoint.ToString(); byte [] buffer = new byte [1024]; Action<IAsyncResult> action = null ; action = new Action<IAsyncResult>(ar => { int received = -1; try { received = src.EndReceive(ar); } catch (Exception exp) { log.ErrorFormat( "src.EndReceive ERROR, srcAddress:{0},{1}" , srcAddress, exp.Message); try { des.Disconnect( false ); log.Debug( "断开连接" + desAddress); } catch {} } if (received > 0) { this .Print(srcAddress, desAddress, buffer, 0, received); try { des.BeginSend(buffer, 0, received, SocketFlags.None, arSend => { try { des.EndSend(arSend); } catch (Exception exp) { log.ErrorFormat( "des.EndSend ERROR, desAddress:{0},{1}" , desAddress, exp.Message); log.Error(exp); try { src.Disconnect( false ); log.Debug( "断开连接" + srcAddress); } catch { } return ; } try { src.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(action), null ); } catch (Exception exp) { log.ErrorFormat( "src.BeginReceive ERROR, srcAddress:{0},{1}" , srcAddress, exp.Message); log.Error(exp); try { des.Disconnect( false ); log.Debug( "断开连接" + desAddress); } catch { } try { src.Disconnect( false ); log.Debug( "断开连接" + srcAddress); } catch { } } }, des); } catch (Exception exp) { log.ErrorFormat( "des.BeginSend ERROR, srcAddress:{0},{1}" , srcAddress, exp.Message); log.Error(exp); try { des.Disconnect( false ); log.Debug( "断开连接" + desAddress); } catch { } try { src.Disconnect( false ); log.Debug( "断开连接" + srcAddress); } catch { } } } else { log.ErrorFormat( "主动断开连接, srcAddress:{0},{1}" , srcAddress, "没有收到数据" ); //应该是断开了 try { des.Disconnect( false ); log.Debug( "断开连接" + desAddress); } catch { } try { src.Disconnect( false ); log.Debug( "断开连接" + srcAddress); } catch { } } }); try { src.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(action), null ); } catch (Exception exp) { log.Debug(exp); try { des.Disconnect( false ); log.Debug( "断开连接" + desAddress); } catch { } try { src.Disconnect( false ); log.Debug( "断开连接" + srcAddress); } catch { } } } private void SetupProxy(ProxyItem proxy) { var p = proxy; SetupTransfer(proxy.RemoteSocket, proxy.Proxy); SetupTransfer(proxy.Proxy, proxy.RemoteSocket); } private void Print( string src, string des, byte [] bytes, int offset , int count) { string str = string .Format( "{0}=>{1}:{2}" , src, des, BitConverter.ToString(bytes, offset, count)); //Console.WriteLine(str); log.Debug(str); } } public class ProxyItem { public Socket RemoteSocket { get ; set ; } public Socket Proxy { get ; set ; } } } |
QQ:273352165
evlon#126.com
转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步