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 TcpRouter
{
class Program
{
private int listenPort;
private string ip;
private int port;
private ConcurrentDictionary<IPEndPoint, ProxyItem> proxies = new ConcurrentDictionary<IPEndPoint, ProxyItem>();
private TcpListener 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("TCP:{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);
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, this.listenPort);
this.listener = new TcpListener(localEP);
listener.Start(100);
listener.BeginAcceptSocket(OnAccepted, listener);
Console.ReadLine();
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
log.Fatal("UnhandledException", (Exception)e.ExceptionObject);
}
public void OnAccepted(IAsyncResult ar)
{
TcpListener listener = ar.AsyncState as TcpListener;
Socket remoteSocket = listener.EndAcceptSocket(ar);
listener.BeginAcceptSocket(OnAccepted, listener);
Socket proxy = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
proxy.BeginConnect(this.ip, this.port, arConn =>
{
try
{
proxy.EndConnect(arConn);
this.SetupProxy(new ProxyItem() { Proxy = proxy, RemoteSocket = remoteSocket });
}
catch (Exception exp)
{
log.Debug(exp.Message);
//断开连接
//remoteSocket.BeginDisconnect(false, ardc => {
// remoteSocket.EndDisconnect(ardc);
//}, remoteSocket);
//改为增加日志
byte[] buffer = new byte[1024];
remoteSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, arRecv =>
{
try
{
int received = remoteSocket.EndReceive(arRecv);
this.Print(remoteSocket.RemoteEndPoint.ToString(), "non", buffer, 0, received);
}
catch (SocketException ex)
{
log.Debug(ex);
}
catch (ObjectDisposedException ex)
{
log.Debug(ex);
}
}, null);
}
}, proxy);
}
catch (Exception exp)
{
log.Debug(exp);
}
}
private void SetupTransfer(Socket src, Socket des)
{
string srcAddress = src.RemoteEndPoint.ToString();
string desAddress = des.RemoteEndPoint.ToString();
byte[] buffer = new byte[1024];
Action<IAsyncResult> action = null;
action = new Action<IAsyncResult>(ar =>
{
int received = -1;
try
{
received = src.EndReceive(ar);
}
catch (Exception exp)
{
log.ErrorFormat("src.EndReceive ERROR, srcAddress:{0},{1}", srcAddress, exp.Message);
try
{
des.Disconnect(false);
log.Debug("断开连接" + desAddress);
}
catch{}
}
if(received > 0)
{
this.Print(srcAddress, desAddress, buffer, 0, received);
try
{
des.BeginSend(buffer, 0, received, SocketFlags.None, arSend =>
{
try
{
des.EndSend(arSend);
}
catch (Exception exp)
{
log.ErrorFormat("des.EndSend ERROR, desAddress:{0},{1}", desAddress, exp.Message);
log.Error(exp);
try
{
src.Disconnect(false);
log.Debug("断开连接" + srcAddress);
}
catch { }
return;
}
try
{
src.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(action), null);
}
catch (Exception exp)
{
log.ErrorFormat("src.BeginReceive ERROR, srcAddress:{0},{1}", srcAddress, exp.Message);
log.Error(exp);
try
{
des.Disconnect(false);
log.Debug("断开连接" + desAddress);
}
catch { }
try
{
src.Disconnect(false);
log.Debug("断开连接" + srcAddress);
}
catch { }
}
}, des);
}
catch (Exception exp)
{
log.ErrorFormat("des.BeginSend ERROR, srcAddress:{0},{1}", srcAddress, exp.Message);
log.Error(exp);
try
{
des.Disconnect(false);
log.Debug("断开连接" + desAddress);
}
catch { }
try
{
src.Disconnect(false);
log.Debug("断开连接" + srcAddress);
}
catch { }
}
}
else
{
log.ErrorFormat("主动断开连接, srcAddress:{0},{1}", srcAddress, "没有收到数据");
//应该是断开了
try
{
des.Disconnect(false);
log.Debug("断开连接" + desAddress);
}
catch { }
try
{
src.Disconnect(false);
log.Debug("断开连接" + srcAddress);
}
catch { }
}
});
try
{
src.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(action), null);
}
catch (Exception exp)
{
log.Debug(exp);
try
{
des.Disconnect(false);
log.Debug("断开连接" + desAddress);
}
catch { }
try
{
src.Disconnect(false);
log.Debug("断开连接" + srcAddress);
}
catch { }
}
}
private void SetupProxy(ProxyItem proxy)
{
var p = proxy;
SetupTransfer(proxy.RemoteSocket, proxy.Proxy);
SetupTransfer(proxy.Proxy, proxy.RemoteSocket);
}
private void Print(string src, string des, byte[] bytes, int offset , int count)
{
string str = string.Format("{0}=>{1}:{2}", src, des, BitConverter.ToString(bytes, offset, count));
//Console.WriteLine(str);
log.Debug(str);
}
}
public class ProxyItem
{
public Socket RemoteSocket { get; set; }
public Socket Proxy { get; set; }
}
}