C#开发的简单端口转发程序的代码

原文链接:https://blog.51cto.com/14406976/2423764

下面代码是关于C#开发的简单端口转发程序的代码。

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace portmap_net
{
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 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
}

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
}

sealed internal class program
{

    #region Fields (4)

    private static StringBuilder _console_buf = new StringBuilder();
    private static readonly Dictionary<int, state> _state_dic = new Dictionary<int, state>();
    #endregion Fields

    #region 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, _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)
        {
            show_state();
            Thread.Sleep(2000);
        }
    }

    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.Listen(10);
        }
        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));
        }
    }

    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 };
        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();
        --_state_dic[work._id]._connect_cnt;
    }

    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

--------------------------------------------------";
}
}
深圳网站建设www.sz886.com

上一篇:C#阻塞模式和非阻塞模式


下一篇:Python脚本实现网卡流量监控