// Example usage: // Terminal 1: python -m http.server 8000 // Terminal 2: go run tcpproxy.go 9000 localhost:8000 // Terminal 3: curl localhost:9000 package main import ( "fmt" "io" "net" "os" ) func main() { if len(os.Args) != 3 { fmt.Println("Usage: go run tcpproxy.go ") os.Exit(1) } listenPort := os.Args[1] // port to listen on targetAddr := os.Args[2] // target server address // create TCP listener on specified port listener, err := net.Listen("tcp", ":"+listenPort) if err != nil { fmt.Printf("Failed to listen on port %s: %v\n", listenPort, err) os.Exit(1) } defer listener.Close() fmt.Printf("TCP proxy listening on port %s, forwarding to %s\n", listenPort, targetAddr) // accept incoming connections for { clientConn, err := listener.Accept() if err != nil { fmt.Printf("Failed to accept connection: %v\n", err) continue } // handle each client connection concurrently go handleConnection(clientConn, targetAddr) } } func handleConnection(clientConn net.Conn, targetAddr string) { defer clientConn.Close() // ensure client connection is closed // connect to target server serverConn, err := net.Dial("tcp", targetAddr) if err != nil { fmt.Printf("Failed to connect to target %s: %v\n", targetAddr, err) return } defer serverConn.Close() // ensure server connection is closed // start bidirectional data copying go io.Copy(serverConn, clientConn) // client -> server io.Copy(clientConn, serverConn) // server -> client (blocks until done) }