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