做外贸仿牌网站,品牌打造,电脑速成班短期电脑培训班,马鞍山seo前段时间, redis作者不是整了个c语言版本的聊天服务器嘛, 地址, 代码量拢共不过百行.
于是, 心血来潮下, 我也整了个Go语言版本. 简单来说就是实现了一个聊天室的功能. 将所有注释空行都去掉, 刚好100行实现. 废话不多说, 先上代码:
package mainimport (fmtfmtlognetstringssync
)type Server struct { // 服务端内容clients map[string]*Clientlock sync.Mutex
}func (s *Server) delClient(client *Client) { // 客户端关闭s.lock.Lock()defer s.lock.Unlock()delete(s.clients, client.name)
}func (s *Server) addClient(client *Client) { // 客户端关闭s.lock.Lock()defer s.lock.Unlock()s.clients[client.name] client
}func (s *Server) sendMsgToOtherClient(msg string, client *Client) { // 将消息发送给其他所有客户端s.lock.Lock()defer s.lock.Unlock()// 将消息转发给其他客户端for _, c : range s.clients {if c ! client {c.msgCh - msg- client.name : msg \n}}
}type Client struct { // 定义客户端conn net.Connname string // 当前客户端的名称msgCh chan string // 发送消息的管道server *Server
}func (c *Client) receive() { // 接收消息for msg : range c.msgCh {_, _ c.conn.Write([]byte(msg))}
}func (c *Client) close() {c.server.delClient(c)close(c.msgCh)_ c.conn.Close()
}func (c *Client) handle() { // 开始处理连接_, _ c.conn.Write([]byte(fmt.Sprintf(hello %s!\n, c.name))) // 发送欢迎信息c.server.sendMsgToOtherClient(join, c) // 通知大家, 有人加入了聊天室defer c.close()for {buf : make([]byte, 2048)n, err : c.conn.Read(buf) // 接收客户端发送的消息if err ! nil {log.Printf(receive client data error: %s, err.Error())return}msg : strings.TrimSpace(string(buf[:n]))if len(msg) 0 {continue}if msg quit {c.server.sendMsgToOtherClient(quit, c) // 通知大家, 有人退出了聊天室return}c.server.sendMsgToOtherClient(msg, c)}
}func main() {// 监听端口listener, err : net.Listen(tcp, :8080)if err ! nil {panic(err)}server : Server{clients: make(map[string]*Client),lock: sync.Mutex{},}nameIndex : 1for {conn, err : listener.Accept() // 建立连接if err ! nil {log.Println(err)continue}client : Client{conn: conn,msgCh: make(chan string, 100),name: fmt.Sprintf(user%d, nameIndex),server: server,}nameIndexserver.addClient(client)go client.handle()go client.receive()log.Printf(new client: %s\n, conn.RemoteAddr())}
}可以直接telnet作为客户端连接, 实现的功能简单来说就是一个大的聊天室, 用户发的消息会同步发给所有用户. (因代码篇幅和复杂度原因, 就不对代码做详细说明了)
看下聊天室效果: 当然了, 还是有很多极限情况没有处理, 很多异常情况没有判断. 比如:
客户端数量没有控制缺少客户端心跳缺少错误处理缺少安全性检查客户端发送消息的长度限制等等…
但总得来说, 作为一个玩具还是可以的, 而且也达到百行的要求咯.(这也是我改了几版才改到百行的…)