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; }
}
}