Skip to content

Instantly share code, notes, and snippets.

@rustyx
Created February 27, 2022 11:05
Show Gist options
  • Save rustyx/602217695edf1571fff45b01b700e30d to your computer and use it in GitHub Desktop.
Save rustyx/602217695edf1571fff45b01b700e30d to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"net"
"os"
"os/exec"
)
func main() {
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
check(err, "ResolveTCPAddr")
conn, err := net.ListenTCP("tcp", addr)
check(err, "ListenTCP")
fmt.Println("listening on:", conn.Addr())
go connectAsClient(conn.Addr().(*net.TCPAddr))
for {
client, err := conn.AcceptTCP()
check(err, "AcceptTCP")
fmt.Println("Accepted from:", client.RemoteAddr())
go serveDoor(client, "echo", "Hello from client!")
}
}
func check(err error, msg string) {
if err != nil {
fmt.Fprintf(os.Stderr, "%s error: %v\n", msg, err)
os.Exit(1)
}
}
func serveDoor(conn *net.TCPConn, name string, args ...string) {
defer conn.Close()
cmd := exec.Command(name, args...)
cmd.Stdin = conn
cmd.Stdout = conn
cmd.Stderr = conn
err := cmd.Run()
fmt.Println("door finished:", err)
}
func connectAsClient(dst *net.TCPAddr) {
conn, err := net.DialTCP("tcp", nil, dst)
check(err, "DialTCP")
defer conn.Close()
var data [512]byte
for {
n, err := conn.Read(data[:])
if err != nil {
if err != io.EOF {
fmt.Println("client read error:", err)
}
break
}
fmt.Printf("client got: %q\n", string(data[:n]))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment