Created
November 1, 2025 22:47
-
-
Save BigRedEye/c811099d862e7a47b4369c832996596b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "flag" | |
| "log/slog" | |
| "net" | |
| "os" | |
| "time" | |
| ) | |
| func main() { | |
| if err := run(); err != nil { | |
| slog.Error("Failed to run tcpping", "error", err) | |
| os.Exit(1) | |
| } | |
| } | |
| var ( | |
| listen = flag.Bool("listen", false, "Whether to be a client or a server") | |
| addr = flag.String("addr", "0.0.0.0:7878", "Address to communicate through") | |
| interval = flag.Duration("interval", time.Second, "Interval between pings") | |
| ) | |
| func run() error { | |
| flag.Parse() | |
| if *listen { | |
| return runServer() | |
| } else { | |
| return runClient() | |
| } | |
| } | |
| func runServer() error { | |
| listener, err := net.Listen("tcp", *addr) | |
| if err != nil { | |
| return err | |
| } | |
| slog.Info("Accepting new connections", "address", listener.Addr()) | |
| nextconnid := 0 | |
| for { | |
| conn, err := listener.Accept() | |
| if err != nil { | |
| slog.Error("Failed to accept", "error", err) | |
| continue | |
| } | |
| connid := nextconnid | |
| nextconnid += 1 | |
| slog.Info("Accepted a new connection", | |
| "address", conn.RemoteAddr(), | |
| "connid", connid, | |
| ) | |
| go pingpong(conn, false, connid) | |
| } | |
| } | |
| func runClient() error { | |
| conn, err := net.Dial("tcp", *addr) | |
| if err != nil { | |
| return err | |
| } | |
| slog.Info("Connected to the server", "address", conn.RemoteAddr()) | |
| pingpong(conn, true, 0) | |
| return nil | |
| } | |
| func pingpong(conn net.Conn, sendrecv bool, connid int) { | |
| log := slog.With("connection", connid) | |
| slog.Info("Starting a ping-pong session") | |
| for iter := 0; ; iter++ { | |
| log := log.With("iter", iter) | |
| if sendrecv { | |
| time.Sleep(*interval) | |
| start := time.Now() | |
| if err := ping(conn); err != nil { | |
| log.Error("Failed to ping remote connection", "error", err) | |
| return | |
| } | |
| log.Info("Pinged remote", "duration", time.Since(start)) | |
| } else { | |
| if err := pong(conn); err != nil { | |
| log.Error("Failed to pong remote connection", "error", err) | |
| return | |
| } | |
| } | |
| sendrecv = !sendrecv | |
| } | |
| } | |
| func ping(conn net.Conn) error { | |
| var buf [1]byte = [1]byte{'a'} | |
| _, err := conn.Write(buf[:]) | |
| if err != nil { | |
| return err | |
| } | |
| _, err = conn.Read(buf[:]) | |
| if err != nil { | |
| return err | |
| } | |
| return nil | |
| } | |
| func pong(conn net.Conn) error { | |
| var buf [1]byte = [1]byte{'a'} | |
| _, err := conn.Read(buf[:]) | |
| if err != nil { | |
| return err | |
| } | |
| slog.Info("Replying back") | |
| _, err = conn.Write(buf[:]) | |
| if err != nil { | |
| return err | |
| } | |
| return nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment