C#开发的简单端口转发程序
发布时间:2020-12-15 17:58:20 所属栏目:百科 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 简单的说就是将指定端口的数据转发到另外一个端口,这样可以跳过某些服务器的防火墙 支持多线程,连接数统计,流量统计 using System;using System.Coll
以下代码由PHP站长网 52php.cn收集自互联网 现在PHP站长网小编把它分享给大家,仅供参考
简单的说就是将指定端口的数据转发到另外一个端口,这样可以跳过某些服务器的防火墙
支持多线程,连接数统计,流量统计 using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace portmap_net { /// <summary> /// 映射器实例状态 /// </summary> sealed internal class state { #region Fields (5) public int _connect_cnt; public string _point_in; public string _point_out; public const string _print_head = "输入IP 输出IP 状态 连接数 接收/发送"; public bool _running; public long _bytes_send; public long _bytes_recv; #endregion Fields #region Constructors (1) public state(string point_in,string point_out,bool running,int connect_cnt,int bytes_send,int bytes_recv) { _point_in = point_in; _point_out = point_out; _running = running; _connect_cnt = connect_cnt; _bytes_recv = bytes_recv; _bytes_send = bytes_send; } #endregion Constructors #region Methods (1) // Public Methods (1) public override string ToString() { return string.Format("{0}{1}{2}{3}{4}",_point_in.PadRight(20,' '),_point_out.PadRight(20,(_running ? "运行中 " : "启动失败"),_connect_cnt.ToString().PadRight(10,Math.Round((double)_bytes_recv / 1024) + "k/" + Math.Round((double)_bytes_send / 1024) + "k"); } #endregion Methods } /// <summary> /// 映射器线程所需数据 /// </summary> internal struct work_item { #region Data Members (4) public int _id; public EndPoint _ip_in; public string _ip_out_host; public ushort _ip_out_port; #endregion Data Members } /// <summary> /// 主程序 /// </summary> sealed internal class program { #region Fields (4) private static StringBuilder _console_buf = new StringBuilder(); /// <summary> /// 程序已启动的所有映射器实例,key=id /// </summary> private static readonly Dictionary<int,state> _state_dic = new Dictionary<int,state>(); #endregion Fields #region Methods (8) // Private Methods (8) private static void Main() { //映射器参数 List<work_item> maps_list = new List<work_item>{ new work_item{_id = 1,_ip_in = new IPEndPoint(IPAddress.Any,2012),_ip_out_host="10.10.1.18",_ip_out_port = 3389 },new work_item{_id = 2,2013),_ip_out_host="www.beta-1.cn",_ip_out_port = 80 } }; //启动映射器 foreach (var map_item in maps_list) map_start(map_item); Console.CursorVisible = false; while (true) { //每2秒刷新屏幕,显示映射器状态 show_state(); Thread.Sleep(2000); } } /// <summary> /// 启动映射器 /// </summary> /// <param name="work"></param> private static void map_start(work_item work) { Socket sock_svr = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); bool start_error = false; try { sock_svr.Bind(work._ip_in);//绑定本机ip sock_svr.Listen(10); sock_svr.BeginAccept(on_local_connected,new object[] { sock_svr,work });//接受connect } catch (Exception) { start_error = true; } finally { _state_dic.Add(work._id,new state(work._ip_in.ToString(),work._ip_out_host + ":" + work._ip_out_port,!start_error,0)); } } /// <summary> /// 收到connect /// </summary> /// <param name="ar"></param> private static void on_local_connected(IAsyncResult ar) { object[] ar_arr = ar.AsyncState as object[]; Socket sock_svr = ar_arr[0] as Socket; work_item work = (work_item)ar_arr[1]; ++_state_dic[work._id]._connect_cnt; Socket sock_cli = sock_svr.EndAccept(ar); sock_svr.BeginAccept(on_local_connected,ar.AsyncState); Socket sock_cli_remote = new Socket(AddressFamily.InterNetwork,ProtocolType.Tcp); try { sock_cli_remote.Connect(work._ip_out_host,work._ip_out_port); } catch (Exception) { try { sock_cli.Shutdown(SocketShutdown.Both); sock_cli_remote.Shutdown(SocketShutdown.Both); sock_cli.Close(); sock_cli_remote.Close(); } catch (Exception) { } --_state_dic[work._id]._connect_cnt; return; } //线程: 接受本地数据 转发至远程 Thread t_send = new Thread(recv_and_send_caller) { IsBackground = true }; //线程: 接受远程数据 转发至本地connect 端 Thread t_recv = new Thread(recv_and_send_caller) { IsBackground = true }; t_send.Start(new object[] { sock_cli,sock_cli_remote,work._id,true }); t_recv.Start(new object[] { sock_cli_remote,sock_cli,false }); //线程同步 t_send.Join(); t_recv.Join(); //已断开,连接数-1 --_state_dic[work._id]._connect_cnt; } /// <summary> /// 数据转发 /// </summary> /// <param name="from_sock"></param> /// <param name="to_sock"></param> /// <param name="send_complete"></param> private static void recv_and_send(Socket from_sock,Socket to_sock,Action<int> send_complete) { byte[] recv_buf = new byte[4096]; int recv_len; while ((recv_len = from_sock.Receive(recv_buf)) > 0) { to_sock.Send(recv_buf,recv_len,SocketFlags.None); send_complete(recv_len); } } private static void recv_and_send_caller(object thread_param) { object[] param_arr = thread_param as object[]; Socket sock1 = param_arr[0] as Socket; Socket sock2 = param_arr[1] as Socket; try { recv_and_send(sock1,sock2,bytes => { state stat = _state_dic[(int)param_arr[2]]; if ((bool)param_arr[3]) stat._bytes_send += bytes; else stat._bytes_recv += bytes; }); } catch (Exception) { try { sock1.Shutdown(SocketShutdown.Both); sock2.Shutdown(SocketShutdown.Both); sock1.Close(); sock2.Close(); } catch (Exception) { } } } private static void show_state() { StringBuilder curr_buf = new StringBuilder(); curr_buf.AppendLine(program_ver); curr_buf.AppendLine(state._print_head); foreach (KeyValuePair<int,state> item in _state_dic) curr_buf.AppendLine(item.Value.ToString()); if (_console_buf.Equals(curr_buf)) return; Console.Clear(); Console.WriteLine(curr_buf); _console_buf = curr_buf; } #endregion Methods private const string program_ver = @"[PortMapNet(0.1) http://www.beta-1.cn] --------------------------------------------------"; } } 以上内容由PHP站长网【52php.cn】收集整理供大家参考研究 如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |