Skip to content

Instantly share code, notes, and snippets.

@calebdoxsey
Created December 6, 2024 22:32
Show Gist options
  • Save calebdoxsey/a7a389edb6133376ec28a5ad1a4028ac to your computer and use it in GitHub Desktop.
Save calebdoxsey/a7a389edb6133376ec28a5ad1a4028ac to your computer and use it in GitHub Desktop.
package main
import (
"context"
"fmt"
"log"
"net"
"os"
"time"
"golang.org/x/sync/errgroup"
)
func main() {
log.SetFlags(0)
err := run(context.Background())
if err != nil {
log.Fatalln(err)
}
}
func run(ctx context.Context) error {
port, ok := os.LookupEnv("PORT")
if !ok {
return fmt.Errorf("PORT is required")
}
srcAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
if err != nil {
return fmt.Errorf("error parsing source address: %w", err)
}
dstAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:"+port)
if err != nil {
return fmt.Errorf("error parsing destination address: %w", err)
}
log.Println("connect", "from", srcAddr, "to", dstAddr.String())
conn, err := net.ListenUDP("udp", srcAddr)
if err != nil {
return fmt.Errorf("failed to start udp connection: %w", err)
}
eg, ctx := errgroup.WithContext(ctx)
eg.Go(func() error {
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
for {
var tm time.Time
select {
case <-ctx.Done():
return context.Cause(ctx)
case tm = <-ticker.C:
}
str := tm.Format(time.RFC3339Nano)
log.Println("send", str, "to", dstAddr.String())
_, err := conn.WriteToUDP([]byte(str), dstAddr)
if err != nil {
return fmt.Errorf("error writing packet: %w", err)
}
}
})
eg.Go(func() error {
for {
var packet [65535]byte
n, srcAddr, err := conn.ReadFromUDP(packet[:])
if err != nil {
return fmt.Errorf("error reading packet: %w", err)
}
log.Println("recv", string(packet[:n]), "from", srcAddr.String())
}
})
return eg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment