package main import ( "bufio" "flag" "fmt" "io" "net" "net/http" "os" "strings" ) var ( host = flag.String("h", "localhost", "Server host") port = flag.String("p", "26666", "Server port") proto = flag.String("proto", "tcp", "Protocol to use (tcp, udp, http)") method = flag.String("method", "get", "HTTP method to use (get, post) - only for http protocol") ) func main() { flag.Parse() switch strings.ToLower(*proto) { case "tcp": runTCPClient() case "udp": runUDPClient() case "http": runHTTPClient() default: fmt.Printf("Unsupported protocol: %s. Use tcp, udp, or http.\n", *proto) } } func runTCPClient() { // Connect to the server conn, err := net.Dial("tcp", *host+":"+*port) if err != nil { fmt.Printf("Failed to connect to server: %v\n", err) return } defer conn.Close() fmt.Printf("Connected to TCP server %s:%s\n", *host, *port) fmt.Println("Type messages to send to the server (type 'exit' to quit):") // Create a scanner to read from standard input scanner := bufio.NewScanner(os.Stdin) // Create a goroutine to read messages from the server go func() { serverScanner := bufio.NewScanner(conn) for serverScanner.Scan() { fmt.Printf("Server: %s\n", serverScanner.Text()) } }() // Read from standard input and send to server for { if !scanner.Scan() { break } message := scanner.Text() if strings.TrimSpace(message) == "exit" { fmt.Println("Exiting...") break } // Send message to server _, err := fmt.Fprintln(conn, message) if err != nil { fmt.Printf("Failed to send message: %v\n", err) break } } if err := scanner.Err(); err != nil { fmt.Printf("Error reading input: %v\n", err) } } func runUDPClient() { // Resolve UDP address addr, err := net.ResolveUDPAddr("udp", *host+":"+*port) if err != nil { fmt.Printf("Failed to resolve UDP address: %v\n", err) return } // Connect to the server conn, err := net.DialUDP("udp", nil, addr) if err != nil { fmt.Printf("Failed to connect to UDP server: %v\n", err) return } defer conn.Close() fmt.Printf("Connected to UDP server %s:%s\n", *host, *port) fmt.Println("Type messages to send to the server (type 'exit' to quit):") // Create a scanner to read from standard input scanner := bufio.NewScanner(os.Stdin) // Create a goroutine to read responses from the server go func() { buf := make([]byte, 1024) for { n, _, err := conn.ReadFromUDP(buf) if err != nil { fmt.Printf("Error reading from UDP server: %v\n", err) return } fmt.Printf("Server: %s\n", string(buf[:n])) } }() // Read from standard input and send to server for { if !scanner.Scan() { break } message := scanner.Text() if strings.TrimSpace(message) == "exit" { fmt.Println("Exiting...") break } // Send message to server _, err := conn.Write([]byte(message)) if err != nil { fmt.Printf("Failed to send message: %v\n", err) break } } if err := scanner.Err(); err != nil { fmt.Printf("Error reading input: %v\n", err) } } func runHTTPClient() { // HTTP server runs on port+1 portInt := parseInt(*port) httpPort := fmt.Sprintf("%d", portInt+1) url := fmt.Sprintf("http://%s:%s/ping", *host, httpPort) fmt.Printf("Connecting to HTTP server %s:%s\n", *host, httpPort) fmt.Println("Type messages to send to the server (type 'exit' to quit):") // Create a scanner to read from standard input scanner := bufio.NewScanner(os.Stdin) // Read from standard input and send to server for { if !scanner.Scan() { break } message := scanner.Text() if strings.TrimSpace(message) == "exit" { fmt.Println("Exiting...") break } // Send message to server var resp *http.Response var err error switch strings.ToLower(*method) { case "post": resp, err = http.Post(url, "text/plain", strings.NewReader(message)) case "get": // For GET requests, we'll add the message as a query parameter getURL := url if message != "" { getURL += "?data=" + message } resp, err = http.Get(getURL) default: fmt.Printf("Unsupported HTTP method: %s. Use get or post.\n", *method) return } if err != nil { fmt.Printf("Failed to send message: %v\n", err) break } // Read response body, err := io.ReadAll(resp.Body) resp.Body.Close() if err != nil { fmt.Printf("Failed to read response: %v\n", err) break } fmt.Printf("Server: %s\n", string(body)) } if err := scanner.Err(); err != nil { fmt.Printf("Error reading input: %v\n", err) } } // Helper function to convert string to int func parseInt(s string) int { var result int fmt.Sscanf(s, "%d", &result) return result }