static async Task CopyAsync(TcpStream src, TcpStream dst, CancellationToken ct) { await src.CopyToAsync(dst, 4096, ct); dst.Shutdown(SocketShutdown.Send); }
static async Task <TcpClient> ForwardAsync(TcpClient src, IPEndPoint dstEP, CancellationToken ct, int timeout) { var srcEP = src.Client.RemoteEndPoint; var dst = new TcpClient(); try { await dst.ConnectAsync(dstEP, ct, timeout); Trace.TraceInformation("Connect: {0} -> {1}", dst.Client.LocalEndPoint, dstEP); using (TcpStream ss = new TcpStream(src, timeout, timeout), ds = new TcpStream(dst, timeout, timeout)) { await Task.WhenAll(CopyAsync(ss, ds, ct), CopyAsync(ds, ss, ct)); } Trace.TraceInformation("Closed: {0} -> {1}", srcEP, dstEP); } catch (OperationCanceledException ex) { Trace.TraceWarning(ex.Message); } catch (TimeoutException ex) { Trace.TraceWarning(ex.Message); } catch (Exception ex) { Trace.TraceError("Forward failed: {0}", ex.Message); } src.Close(); dst.Close(); return(null); }