IM:基础连接
1、服务端
go
// server.go
package main
import (
"bufio"
"fmt"
"net"
"strings"
"sync"
)
var (
clients = make(map[net.Conn]string)
mu sync.Mutex
)
func broadcast(msg string, sender net.Conn) {
mu.Lock()
defer mu.Unlock()
for conn := range clients {
if conn != sender {
fmt.Fprintln(conn, msg)
}
}
}
func handleClient(conn net.Conn) {
defer conn.Close()
// 读取用户名(第一行)
reader := bufio.NewReader(conn)
username, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading username:", err)
return
}
username = strings.TrimSpace(username)
if username == "" {
username = "Anonymous"
}
mu.Lock()
clients[conn] = username
mu.Unlock()
fmt.Printf("User %s joined.\n", username)
broadcast(fmt.Sprintf("[Server] %s joined the chat.", username), conn)
// 广播消息循环
for {
msg, err := reader.ReadString('\n')
if err != nil {
break
}
msg = strings.TrimSpace(msg)
if msg == "" {
continue
}
fullMsg := fmt.Sprintf("[%s] %s", username, msg)
fmt.Println(fullMsg) // 服务端日志
broadcast(fullMsg, conn)
}
// 用户断开
mu.Lock()
delete(clients, conn)
mu.Unlock()
broadcast(fmt.Sprintf("[Server] %s left the chat.", username), nil)
fmt.Printf("User %s disconnected.\n", username)
}
func main() {
listener, err := net.Listen("tcp", ":8080")
if err != nil {
panic(err)
}
defer listener.Close()
fmt.Println("IM Server started on :8080")
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Accept error:", err)
continue
}
go handleClient(conn)
}
}
2、客户端
go
// client.go
package main
import (
"bufio"
"fmt"
"net"
"os"
"strings"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
panic(err)
}
defer conn.Close()
fmt.Print("Enter your username: ")
reader := bufio.NewReader(os.Stdin)
username, _ := reader.ReadString('\n')
username = strings.TrimSpace(username)
// 发送用户名
fmt.Fprintln(conn, username)
// 启动 goroutine 接收消息
go func() {
in := bufio.NewScanner(conn)
for in.Scan() {
fmt.Println(in.Text())
}
}()
// 主线程发送消息
for {
fmt.Print("> ")
msg, _ := reader.ReadString('\n')
msg = strings.TrimSpace(msg)
if msg == "/quit" {
break
}
fmt.Fprintln(conn, msg)
}
}