go写了一个简洁版的聊天室实现功能
1.广播用户登录
2.广播群发消息
3.修改当前登录用户名
4.广播用户退出

​服务端代码​

package main

import (
"log"
"net"
"strings"
)
type Client struct {
C chan string
Name string
Addr string
}
var onLineMap map[string]Client
var Message=make(chan string)
var isQuit=make(chan bool)

func WriteMsg(clnt Client, conn net.Conn){
for msg:=range clnt.C {
msg:=msg+"\n"
conn.Write([]byte(msg))
}
}

//广播所有用户消息
func tellAllUser(conn net.Conn,clnt Client){
addr:= conn.RemoteAddr().String()
buf:=make([]byte,1024)
for {
n,err:=conn.Read(buf)
if n == 0 {
log.Println("客户端退休")
isQuit <-true
return
}
if err != nil {
log.Println("system is errors")
return
}
content:=string(buf[:n])
if content == "who" && len(content) == 3 {
conn.Write([]byte("用户列表:\n"))
for _,item:=range onLineMap {
userInfo:= item.Addr+":"+item.Name+"\n"
conn.Write([]byte(userInfo))
}
}else if len(content) >=8 && content[:6] == "rename"{
newName:= strings.Split(content,"|")
clnt.Name = newName[1]
onLineMap[addr]=clnt
}else{
msg:="客户端消息: "+content
Message <-msg
}

}
}


//处理连接出来的用户
func HandleConnect(conn net.Conn){
netAddr:=conn.RemoteAddr().String()
clnt:=Client{
C:make(chan string),
Name: netAddr,
Addr: netAddr,
}
//创建专门当前用户发送消息的go协程
onLineMap[netAddr]=clnt
go WriteMsg(clnt,conn)
//发送用户上校消息导全局通道
msg:="欢迎用户:"+netAddr+"登录"
Message<-msg

go tellAllUser(conn,clnt)//广播所有用户消息

for {
select {
case <-isQuit:
delete(onLineMap,netAddr)
Message <-clnt.Name+"login out"
return
}
}
}
func Manager(){
onLineMap=make(map[string]Client)
for {
msg:=<-Message
for _,clnt:=range onLineMap {
clnt.C <-msg
}
}
}

func main(){
listener,err:= net.Listen("tcp","127.0.0.1:8007")
if err != nil {
log.Println("open tcp is errors")
}
defer listener.Close()
go Manager()//存储用户消息
for {
conn,err:=listener.Accept()
if err != nil {
log.Println("Accept is erros")
}
go HandleConnect(conn)
}

}

​客户端代码​

package main

import (
"bufio"
"fmt"
"io"
"net"
"os"
"strings"
)
func read(conn net.Conn){
defer conn.Close()
var buf[1024]byte
reader:=bufio.NewReader(conn)
for {
n,err:=reader.Read(buf[:])
if err == io.EOF {
break
}
if err != nil {
return
}
recvStr:= string(buf[:n])
fmt.Printf("收到服务端数据为:%v\n",recvStr)
}
}

func main(){
conn,err:= net.Dial("tcp","127.0.0.1:8007")
if err != nil {
fmt.Println("is erro")
}
go read(conn)
reader:= bufio.NewReader(os.Stdin)
fmt.Printf("%v,\n","请写入内容")
for {
text,_:=reader.ReadString('\n')
text = strings.TrimSpace(text)
if text == "exit" {
break
}
conn.Write([]byte(text))
}
conn.Close()
}