中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

C#開發(fā)的簡單端口轉發(fā)程序

2018-07-20    來源:open-open

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用
簡單的說就是將指定端口的數(shù)據(jù)轉發(fā)到另外一個端口,這樣可以跳過某些服務器的防火墻
支持多線程, 連接數(shù)統(tǒng)計, 流量統(tǒng)計
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
 
namespace portmap_net
{
    /// <summary>
    /// 映射器實例狀態(tài)
    /// </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              狀態(tài)    連接數(shù)    接收/發(fā)送";
        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>
    /// 映射器線程所需數(shù)據(jù)
    /// </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()
        {
            //映射器參數(shù)
            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, _ip_in = new IPEndPoint(IPAddress.Any,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秒刷新屏幕, 顯示映射器狀態(tài)
                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;
            }
            //線程: 接受本地數(shù)據(jù) 轉發(fā)至遠程
            Thread t_send = new Thread(recv_and_send_caller) { IsBackground = true };
            //線程: 接受遠程數(shù)據(jù) 轉發(fā)至本地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();
            //已斷開, 連接數(shù)-1
            --_state_dic[work._id]._connect_cnt;
        }
 
        /// <summary>
        /// 數(shù)據(jù)轉發(fā)
        /// </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)  http://www.beta-1.cn]
--------------------------------------------------";
    }
}

標簽: 防火墻 服務器

版權申明:本站文章部分自網(wǎng)絡,如有侵權,請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:C#常用目錄文件操作封裝類代碼

下一篇:自定義C#讀寫ini文件的封裝類