请用golang写一个简单的聊天室,包含服务端客户端
匿名 · 更新于 2023/3/20
以下是一个简单的 Golang 聊天室示例,包括服务端和客户端:
服务端代码:
package mainimport ( "fmt" "net" )
type client chan<- string // 只能发送 string 类型的消息的通道类型别名
var ( entering = make(chan client) leaving = make(chan client) messages = make(chan string) // 所有客户端共享的消息通道 )
func broadcaster() { clients := make(map[client]bool) // 客户端集合 for { select { case msg := <-messages: // 把收到的消息发送给所有客户端 for cli := range clients { cli <- msg } case cli := <-entering: // 新客户端连接 clients[cli] = true cli <- "Welcome to the chat room!" case cli := <-leaving: // 客户端离开 delete(clients, cli) close(cli) } } }
func handleConn(conn net.Conn) { ch := make(chan string) // 发送给客户端的消息通道 go clientWriter(conn, ch)
who := conn.RemoteAddr().String() ch <- "You are " + who messages <- who + " has arrived" entering <- ch input := make(chan string) // 接收客户端的消息通道 go clientReader(conn, input) for { select { case line, ok := <-input: if !ok { break } messages <- who + ": " + line } } leaving <- ch messages <- who + " has left" conn.Close()}
func clientWriter(conn net.Conn, ch <-chan string) { for msg := range ch { fmt.Fprintln(conn, msg) } }
func clientReader(conn net.Conn, ch chan<- string) { buf := make([]byte, 1024) for { n, err := conn.Read(buf) if err != nil { break } ch <- string(buf[:n]) } close(ch) }
func main() { listener, err := net.Listen("tcp", ":8888") if err != nil { panic(err) }
go broadcaster() for { conn, err := listener.Accept() if err != nil { fmt.Printf("failed to accept connection: %s\n", err) continue } go handleConn(conn) }}
客户端代码:
package mainimport ( "bufio" "fmt" "net" "os" "strings" )
func main() { conn, err := net.Dial("tcp", "localhost:8888") if err != nil { panic(err) } defer conn.Close()
go func() { // 接收服务端的消息并输出到控制台 scanner := bufio.NewScanner(conn) for scanner.Scan() { fmt.Println(scanner.Text()) } }() // 从控制台读取输入并发送到服务端 scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() if strings.TrimSpace(line) == "" { continue } fmt.Fprintf(conn, "%s\n", line) }}
运行服务端代码后,可以同时运行多个客户端连接到聊天服务器
