2026-06-16
go
0

从没代码到能跑起来的完整 TCP 网络程序,麻雀虽小五脏俱全。client-server 模型、goroutine 并发、消息广播,Go 网络编程最核心的东西都在里面了。

go
package main import ( "bufio" "fmt" "net" "sync" ) var ( clients = make(map[net.Conn]bool, 1000) mu sync.Mutex ) func main() { listener, err := net.Listen("tcp", ":9999") if err != nil { panic(err.Error()) } defer listener.Close() for { conn, _ := listener.Accept() go handleconn(conn) } } func handleconn(conn net.Conn) { defer conn.Close() mu.Lock() clients[conn] = true mu.Unlock() broadcast(conn, fmt.Sprintf("New Friend Join,Now All People Num: %d", len(clients))) scanner := bufio.NewScanner(conn) for scanner.Scan() { msg := scanner.Text() if scanner.Err() != nil { fmt.Println(scanner.Err().Error()) break } if msg == `\q` { break } broadcast(conn, msg) } broadcast(conn, "A Frend Left.") } func broadcast(sender net.Conn, msg string) { mu.Lock() defer mu.Unlock() for client := range clients { if client != sender { fmt.Fprintln(client, msg) } } } ```go package main import ( "bufio" "fmt" "net" "os" "strings" ) func main() { conn, _ := net.Dial("tcp", ":9999") defer conn.Close() go func() { scanner := bufio.NewScanner(conn) for scanner.Scan() { if scanner.Err() != nil { fmt.Println(scanner.Err().Error()) break } msg := scanner.Text() fmt.Printf("Message:%s\n", msg) } }() scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { if scanner.Err() != nil { fmt.Println(scanner.Err().Error()) break } text := scanner.Text() if strings.TrimSpace(text) == `\q` { fmt.Println("Out!") break } _, err := fmt.Fprintln(conn, text) if err != nil { fmt.Println("send message error", err.Error()) break } } }