package main import ( "fmt" "log" "net" "strings" "time" ) func handshakee(handshakerAddress, localAddress string, name, target string) { // Get our address as a usable UDPAddr. remoteAddr, _ := net.ResolveUDPAddr("udp", handshakerAddress) // Get a random local port. localAddr, _ := net.ResolveUDPAddr("udp", localAddress) log.Printf("Attempting to listen on %s\n", localAddr.String()) // Start listening! localConn, err := net.ListenUDP("udp", localAddr) if err != nil { log.Fatal(err) } go func() { log.Println("Sending REG") _, err := localConn.WriteTo([]byte(fmt.Sprintf("REG %s", name)), remoteAddr) if err != nil { panic(err) } if target != "" { log.Printf("Sending AWAIT for %s\n", target) _, err := localConn.WriteTo([]byte(fmt.Sprintf("AWAIT %s", target)), remoteAddr) if err != nil { panic(err) } } }() listen(localConn, name) } func listen(conn *net.UDPConn, name string) { log.Printf("Listening on %s\n", conn.LocalAddr().String()) for { buffer := make([]byte, 1024) bytesRead, fromAddr, err := conn.ReadFromUDP(buffer) if err != nil { fmt.Println("[ERROR]", err) continue } msg := string(buffer[0:bytesRead]) parts := strings.Split(msg, " ") if parts[0] == "ARRIVED" { log.Printf("recv ARRIVED for %s\n", parts[1]) otherAddr, _ := net.ResolveUDPAddr("udp", parts[1]) conn.WriteTo([]byte(fmt.Sprintf("HELLO %s", name)), otherAddr) go chatWith(conn, name, parts[1]) } else if parts[0] == "HELLO" { log.Printf("recv HELLO from %s\n", fromAddr.String()) go chatWith(conn, name, fromAddr.String()) } else { fmt.Printf("Unhandled: %+v\n", parts) } } } func chatWith(conn *net.UDPConn, name string, otherClient string) { log.Printf("Beginning chat with %s\n", otherClient) otherAddr, _ := net.ResolveUDPAddr("udp", otherClient) for { log.Println("Sending hello...") bytesWritten, err := conn.WriteTo([]byte(fmt.Sprintf("Hello from %s", name)), otherAddr) if err != nil { log.Printf("err: %s\n", err) } else { log.Printf("... wrote %d bytes.\n", bytesWritten) } time.Sleep(5 * time.Second) } }