• 端口映射


    using ConsoleApplication1;
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
     
    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()
            {
                //BLL.Port_Forwarding Bpf = new BLL.Port_Forwarding();
     
                //List<Model.Port_Forwarding> List_Mpf = Bpf.GetModelList("");
     
                ////映射器参数
                //List<work_item> maps_list = new List<work_item>();
     
                //foreach (Model.Port_Forwarding Mpf in List_Mpf)
                //{
                //    if (Mpf.State == 0)
                //    {
                //        maps_list.Add(new work_item { _id = Mpf.Id, _ip_in = new IPEndPoint(IPAddress.Any, int.Parse(Mpf.Port)), _ip_out_host = Mpf.Ip_out.Split(':')[0], _ip_out_port = ushort.Parse(Mpf.Ip_out.Split(':')[1]) });
                //        Mpf.State = 1;
                //        Bpf.Update(Mpf);
                //    }
                //}
     
                //映射器参数
                List<work_item> maps_list = new List<work_item>{
                     new work_item{_id = 1, _ip_in = new IPEndPoint(IPAddress.Any,13122), _ip_out_host="172.16.0.22", _ip_out_port = 808 },
                     new work_item{_id = 2, _ip_in = new IPEndPoint(IPAddress.Any,13123), _ip_out_host="172.16.0.2", _ip_out_port = 808 },
                     new work_item{_id = 3, _ip_in = new IPEndPoint(IPAddress.Any,13120), _ip_out_host="172.16.0.20", _ip_out_port = 808 }
                };
     
                //启动映射器
                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, 0, 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, SocketType.Stream, 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, work._id, 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, 0, 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)]--------------------------------------------------";
        }
    }
  • 相关阅读:
    aspjpeg组件安装、使用常见问题
    调用过程sub时不能使用括号
    asp中,使用js打开别的网址注意点
    让文件夹属性出现“安全”选项卡
    C#正则表达式使用<转载备用>
    .NET编程中常用的路径表示方式<转>
    DIVWEB布局
    winform report<收藏>
    Delphi中MessageBox用法
    DW中常用标签
  • 原文地址:https://www.cnblogs.com/XuPengLB/p/5786224.html
Copyright © 2020-2023  润新知