一、server端
package main
import (
"fmt"
"net"
)
var message = make(chan string)
type client struct {
Name string
Addr string
C chan string
}
var online = make(map[string]client)
func main() {
listener, err := net.Listen("tcp", "127.0.0.1:8089")
if err != nil {
fmt.Println("listen err:", err)
return
}
go manager()
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println(err)
continue
}
go userlogin(conn)
}
}
func userlogin(conn net.Conn) {
defer conn.Close()
addr := conn.RemoteAddr().String()
//将用户加入到在线用户列表
cli := client{addr, addr, make(chan string)}
online[addr] = cli
go writeToclient(cli, conn)
//将用户登录的信息发送到全局message
message <- fmt.Sprintf("用户%s登录", addr)
for {
content := make([]byte, 128)
n, err := conn.Read(content)
if err != nil {
break
}
txt := string(content[:n])
if txt == "quit" {
delete(online, addr)
message <- fmt.Sprintf("用户%s退出!!!", addr)
break
}
txt = addr + " 说话:" + txt
message <- txt
}
}
func manager() {
for {
msg := <-message
fmt.Println("manager管理", msg)
//把上线下线的消息通知给所有用户
for _, user := range online {
user.C <- msg
}
}
}
func writeToclient(cli client, conn net.Conn) {
for {
msg := <-cli.C
conn.Write([]byte("to client" + msg + "\n"))
}
}
二、client端
package main
import (
"bufio"
"fmt"
"io"
"net"
"os"
"strings"
)
var ch1 = make(chan string)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8089")
if err != nil {
return
}
go write(conn)
for {
fmt.Println(<-ch1)
fmt.Print("请输入:")
stdin := bufio.NewReader(os.Stdin)
speak, err := stdin.ReadString('\n')
if err != nil {
fmt.Println("send message error", err)
return
}
speak = strings.TrimSpace(speak)
conn.Write([]byte(speak))
if speak == "quit" {
break
}
}
}
func write(conn net.Conn) {
content := make([]byte, 128)
for {
n, err := conn.Read(content)
if err != nil {
if err == io.EOF {
return
}
fmt.Println("err", err)
}
ch1 <- string(content[:n])
}
}