package cmd import ( "bufio" "fmt" "log" "net" "strings" ) var ( listenPort string = "1302" ) type Creator interface { CreateUser() } type User struct { Username string IP string } func (u User) CreateUser(usr string, ip string) User { u.Username = usr u.IP = ip return u } func Server() { ln, err := net.Listen("tcp", ":"+listenPort) if err != nil { log.Fatalf("Error happened trying to listen on port: %v\n", err) } defer ln.Close() fmt.Printf("Listening on port %v...\n", listenPort) for { conn, err := ln.Accept() if err != nil { log.Fatalf("Error happened trying to accept connection: %v\n", err) } go handleConn(conn) } } func getUsername(conn net.Conn) (s string, err error) { conn.Write([]byte("What's your name?\nChoice: ")) name, err := bufio.NewReader(conn).ReadString('\n') if err != nil { return "", err } trimmedName := strings.TrimRight(name, "\n") return trimmedName, nil } func getUserInput(conn net.Conn) (s string, err error) { message, err := bufio.NewReader(conn).ReadString('\n') if err != nil { return "", err } return message, nil } func handleConn(conn net.Conn) { defer conn.Close() ////////////////////////////////// // Get user information ////////////////////////////////// userName, err := getUsername(conn) if err != nil { log.Printf("Error occurred getting username: %v\n", err) return } userIP := getIP(conn) ////////////////////////////////// newUserTemplate := new(User) newUser := newUserTemplate.CreateUser(userName, userIP) joinMessage := fmt.Sprintf("%v has joined the chat!", newUser.Username) fmt.Println(joinMessage) conn.Write([]byte(joinMessage)) ////////////////////////////////// for { message, err := getUserInput(conn) if err != nil { quitMessage := fmt.Sprintf("%v has disconnected!\n", newUser.Username) fmt.Print(quitMessage) if _, err := conn.Write([]byte(quitMessage)); err != nil { log.Printf("Error happened sending disconnect message: %v", err) } return } finalMessage := fmt.Sprintf("[%v] %v: %v", newUser.IP, newUser.Username, strings.TrimRight(message, "\n")) fmt.Printf("%v\n", finalMessage) if _, err := conn.Write([]byte(finalMessage)); err != nil { log.Printf("Error happened sending message: %v", err) } } ////////////////////////////////// } func getIP(conn net.Conn) (IP string) { if addr, ok := conn.RemoteAddr().(*net.TCPAddr); ok { IP = fmt.Sprintf("%v", addr.IP) } return IP }