UDPRouter

调试UDP包交互时,在网上没有找到一个好的端口转发工具。便自己实现了一个UDP端口转发器。

.net 4.0

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace UdpRouter
{
    class Program
    {
        private int listenPort;
        private string ip;
        private int port;
        private ConcurrentDictionary<IPEndPoint, ProxyItem> proxies = new ConcurrentDictionary<IPEndPoint, ProxyItem>();
        private UdpClient 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("{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);
            this.listener = new UdpClient(this.listenPort);

            listener.BeginReceive(OnReceived, listener);

            Console.ReadLine();
        }

        void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            log.Fatal("UnhandledException", (Exception)e.ExceptionObject);
        }

        public void OnReceived(IAsyncResult ar)
        {
            UdpClient l = ar.AsyncState as UdpClient;

            
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] bytes = l.EndReceive(ar, ref remoteEP);

            bool isNewProxy = false;
            var proxy = this.proxies.GetOrAdd(remoteEP, (ep) =>
                {
                    isNewProxy = true;

                    var ret = new ProxyItem()
                    {
                        RemoteEP = ep,
                        Client = new UdpClient()
                    };



                    

                    return ret;

                });

            proxy.Client.Send(bytes, bytes.Length, this.ip, this.port);

            if (isNewProxy)
            {
                this.SetupProxy(proxy);
            }

            this.Print(remoteEP.ToString(), string.Format("{0}:{1}", this.ip, this.port), bytes);

            l.BeginReceive(OnReceived, l);
                
        }

        



        private void SetupProxy(ProxyItem proxy)
        {
            var p = proxy;
            Action<IAsyncResult> action = null;
            action = new Action<IAsyncResult>(ar =>
                {
                    UdpClient c = ar.AsyncState as UdpClient;
                    IPEndPoint serverEP = new IPEndPoint(IPAddress.Any, 0);
                    byte[] bytes = c.EndReceive(ar, ref serverEP);

                    this.Print(serverEP.ToString(), p.RemoteEP.ToString(), bytes);

                    this.listener.BeginSend(bytes, bytes.Length, p.RemoteEP, arSend => {
                        UdpClient l = arSend.AsyncState as UdpClient;

                        l.EndSend(arSend);


                    }, this.listener);


                    c.BeginReceive(new AsyncCallback(action), c);

                });

            try
            {
                if (!proxy.IsReceiving)
                {
                    proxy.Client.BeginReceive(new AsyncCallback(action), proxy.Client);
                    proxy.IsReceiving = true;
                }
            }
            catch (SocketException exp)
            {
                Console.WriteLine(exp.Message);
            }
        }


        private void Print(string src, string des, byte[] bytes)
        {
            string str = string.Format("{0}=>{1}:{2}", src, des, BitConverter.ToString(bytes));
            Console.WriteLine(str);
            log.Debug(str);
        }
    }


    public class ProxyItem
    {

        public IPEndPoint RemoteEP { get; set; }

        public UdpClient Client { get; set; }

        public bool IsReceiving { get; set; }
    }
}

 

QQ:273352165 evlon#126.com 转载请注明出处。
标签: udp, router
posted @ 2011-12-26 09:32 阿牛 阅读(11) 评论(0) 编辑 收藏