From 70d3daeccbed9abc7601833e48aefaf4e94d89e8 Mon Sep 17 00:00:00 2001 From: "Peter J. Holzer" Date: Sun, 20 Dec 2020 14:51:54 +0100 Subject: [PATCH] Time packets sent from server to client --- tcpdelay.go | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 tcpdelay.go diff --git a/tcpdelay.go b/tcpdelay.go new file mode 100644 index 0000000..3f7a952 --- /dev/null +++ b/tcpdelay.go @@ -0,0 +1,95 @@ +package main + +import ( + "encoding/binary" + "gopkg.in/alecthomas/kingpin.v2" + "fmt" + "log" + "net" + "os" + "time" +) + +var ( + app = kingpin.New("tcpdelay", "Measure TCP delays") + + server = app.Command("server", "Run as server") + listenAddress = server.Arg("address", "Address:port to listen on").String() + + client = app.Command("client", "Request measurement") + serverAddress = client.Arg("address", "Address:port to connect to").String() +) + +func tcpdelayServer() { + ln, err := net.Listen("tcp", *listenAddress) + if err != nil { + log.Fatal("Cannot listen on ", *listenAddress, err) + } + log.Println("Listening on ", ln.Addr()) + for { + conn, err := ln.Accept() + log.Println("accepted connection") + if err != nil { + log.Fatal("Cannot accept on ", listenAddress, err) + } + o := 0 + t0 := time.Now() + d, _ := time.ParseDuration("1s") + te := t0.Add(d) + buffer := make([]byte, 1024) + for t := time.Now(); t.Before(te); t = time.Now() { + copy(buffer[0:8], "tcpdelay") + binary.BigEndian.PutUint64(buffer[8:], uint64(o)) + binary.BigEndian.PutUint64(buffer[16:], uint64(t.UnixNano())) + n, err := conn.Write(buffer) + if err != nil { + log.Fatal("Cannot write on ", listenAddress, err) + } + if n != len(buffer) { + log.Fatal("Wrote ", n, " bytes intead of ", len(buffer)) + } + o += n + } + conn.Close() + log.Println("closed connection") + } +} + +func tcpdelayClient() { + conn, err := net.Dial("tcp", *serverAddress) + if err != nil { + log.Fatal("Cannot connect to ", *serverAddress, err) + } + o := 0 + buffer := make([]byte, 1024) + for { + n, err := conn.Read(buffer) + if err != nil { + log.Fatal("Cannot read from ", *serverAddress, err) + } + if n != len(buffer) { + log.Fatal("Read ", n, " bytes intead of ", len(buffer)) + } + tr := time.Now().UnixNano() + if string(buffer[0:8]) != "tcpdelay" { + log.Fatal("Unexpected magic ", buffer[0:8]) + } + oSent := int(binary.BigEndian.Uint64(buffer[8:])) + if oSent != o { + log.Fatal("Unexpected offset ", oSent, " instead of ", o) + } + ts := binary.BigEndian.Uint64(buffer[16:]) + fmt.Println(o, ts, tr) // XXX - buffer for performance + o += n + } + +} + +func main() { + switch kingpin.MustParse(app.Parse(os.Args[1:])) { + case server.FullCommand(): + tcpdelayServer() + case client.FullCommand(): + tcpdelayClient() + } +}