76 lines
1.6 KiB
Go
76 lines
1.6 KiB
Go
![]() |
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"net"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
clients = make(map[net.Conn]string) // 连接映射:连接对象到用户名
|
||
|
clientsMu sync.Mutex // 保护clients的互斥锁
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
listener, err := net.Listen("tcp", ":8888")
|
||
|
if err != nil {
|
||
|
log.Fatalf("监听端口失败: %v", err)
|
||
|
}
|
||
|
defer listener.Close()
|
||
|
fmt.Println("服务器已启动,监听端口 8888")
|
||
|
|
||
|
for {
|
||
|
conn, err := listener.Accept()
|
||
|
if err != nil {
|
||
|
log.Printf("接受连接失败: %v", err)
|
||
|
continue
|
||
|
}
|
||
|
go handleConnection(conn)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func handleConnection(conn net.Conn) {
|
||
|
defer func() {
|
||
|
// 连接关闭时,移除客户端
|
||
|
clientsMu.Lock()
|
||
|
delete(clients, conn)
|
||
|
clientsMu.Unlock()
|
||
|
conn.Close()
|
||
|
broadcast(fmt.Sprintf("用户退出:%s", conn.RemoteAddr().String()), "系统")
|
||
|
fmt.Printf("客户端断开:%s\n", conn.RemoteAddr().String())
|
||
|
}()
|
||
|
|
||
|
// 添加新连接
|
||
|
clientsMu.Lock()
|
||
|
clients[conn] = conn.RemoteAddr().String()
|
||
|
clientsMu.Unlock()
|
||
|
|
||
|
// 通知所有客户端有新用户加入
|
||
|
broadcast(fmt.Sprintf("新用户加入:%s", conn.RemoteAddr().String()), "系统")
|
||
|
|
||
|
scanner := bufio.NewScanner(conn)
|
||
|
for scanner.Scan() {
|
||
|
msg := scanner.Text()
|
||
|
sender := clients[conn]
|
||
|
broadcast(msg, sender)
|
||
|
}
|
||
|
if err := scanner.Err(); err != nil {
|
||
|
log.Printf("读取消息错误: %v", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func broadcast(message, sender string) {
|
||
|
clientsMu.Lock()
|
||
|
defer clientsMu.Unlock()
|
||
|
for c := range clients {
|
||
|
if c != nil {
|
||
|
_, err := fmt.Fprintf(c, "[%s] %s\n", sender, message)
|
||
|
if err != nil {
|
||
|
log.Printf("广播失败: %v", err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|