Warning: this should only be used for testing purposes, as it will leak threads.
using System; using System.Net; using System.Net.Sockets; using System.Threading; class Program { static void ProxyStream(string stream1name, NetworkStream stream1, string stream2name, NetworkStream stream2) { var buffer = new byte[65536]; try { while (true) { var len = stream1.Read(buffer, 0, 65536); stream2.Write(buffer, 0, len); } } catch (Exception) { Console.WriteLine("Stream from " + stream1name + " to " + stream2name + " closed"); } } static void Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Usage: program.exe localport remoteServerHost remoteServerPort"); Console.WriteLine("Example: program.exe 13389 10.1.2.3 3389"); return; } var localPort = int.Parse(args[0]); var remoteServerHost = args[1]; var remoteServerPort = int.Parse(args[2]); var l = new TcpListener(IPAddress.Any, localPort); l.Start(); while (true) { var client1 = l.AcceptTcpClient(); var remoteAddress = (client1.Client.RemoteEndPoint as IPEndPoint).Address.ToString(); Console.WriteLine("Accepted session from " + remoteAddress); var client2 = new TcpClient(remoteServerHost, remoteServerPort); Console.WriteLine("Created connection to " + remoteServerHost + ":" + remoteServerPort); new Thread(() => { ProxyStream(remoteAddress, client1.GetStream(), remoteServerHost, client2.GetStream()); }).Start(); new Thread(() => { ProxyStream(remoteServerHost, client2.GetStream(), remoteAddress, client1.GetStream()); }).Start(); } } }
Or, if you need this from PowerShell, I would suggest wrapping it (as threads in PowerShell are painful):
$source = ' using System; using System.Net; using System.Net.Sockets; using System.Threading; class Program { static void ProxyStream(string stream1name, NetworkStream stream1, string stream2name, NetworkStream stream2) { var buffer = new byte[65536]; try { while (true) { var len = stream1.Read(buffer, 0, 65536); stream2.Write(buffer, 0, len); } } catch (Exception) { Console.WriteLine("Stream from " + stream1name + " to " + stream2name + " closed"); } } static void Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Usage: program.exe localport remoteServerHost remoteServerPort"); Console.WriteLine("Example: program.exe 13389 10.1.2.3 3389"); return; } var localPort = int.Parse(args[0]); var remoteServerHost = args[1]; var remoteServerPort = int.Parse(args[2]); var l = new TcpListener(IPAddress.Any, localPort); l.Start(); while (true) { var client1 = l.AcceptTcpClient(); var remoteAddress = (client1.Client.RemoteEndPoint as IPEndPoint).Address.ToString(); Console.WriteLine("Accepted session from " + remoteAddress); var client2 = new TcpClient(remoteServerHost, remoteServerPort); Console.WriteLine("Created connection to " + remoteServerHost + ":" + remoteServerPort); new Thread(() => { ProxyStream(remoteAddress, client1.GetStream(), remoteServerHost, client2.GetStream()); }).Start(); new Thread(() => { ProxyStream(remoteServerHost, client2.GetStream(), remoteAddress, client1.GetStream()); }).Start(); } } } ' Add-Type ` -TypeDefinition $source ` -Language CSharp ` -OutputAssembly 'c:\windows\temp\tcpproxy.exe' ` -OutputType 'ConsoleApplication'