博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang实现简单tcp服务器03 -- 文本广播式聊天服务器/客户端
阅读量:6335 次
发布时间:2019-06-22

本文共 2525 字,大约阅读时间需要 8 分钟。

hot3.png

用Golang实现 文本广播式聊天服务器/客户端

本节, 我们将一步一步的把上一节完成的echo服务器/客户端改造成一个文本信息的聊天室

服务端的改动

  1. 服务器为了实现聊天信息的群体广播, 需要记录所有连接到服务器的客户端信息, 所以, 我们需要添加一个集合来保存所有客户端的连接:

    var ConnMap map[string]*net.TCPConn

  2. 接着, 每次当有新的客户端连接到服务器时, 需要把这个客户端连接行信息加入集合:

    ConnMap[tcpConn.RemoteAddr().String()] = tcpConn

  3. 当服务器收到客户端的聊天信息时, 需要广播到所有客户端, 所以我们需要利用上面保存TCPConn的map来遍历所有TCPConn进行广播, 用以下方法实现:

    func boradcastMessage(message string) { 	b := []byte(message) 	for _, conn := range ConnMap { 	conn.Write(b) 	} }

客户端代码改动

客户端代码改动相对简单, 只是加入了用户自己输入聊天信息的功能, 在连接成功并且 启动了消息接收的gorountine后, 加入以下代码:

for {		var msg string		fmt.Scanln(&msg)		if msg == "quit" {			break		}		b := []byte(msg + "\n")		conn.Write(b)	}

完整的服务端代码如下:

server.go

package mainimport (	"bufio"	"fmt"	"net")// 用来记录所有的客户端连接var ConnMap map[string]*net.TCPConnfunc main() {	var tcpAddr *net.TCPAddr	ConnMap = make(map[string]*net.TCPConn)	tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:9999")	tcpListener, _ := net.ListenTCP("tcp", tcpAddr)	defer tcpListener.Close()	for {		tcpConn, err := tcpListener.AcceptTCP()		if err != nil {			continue		}		fmt.Println("A client connected : " + tcpConn.RemoteAddr().String())		// 新连接加入map		ConnMap[tcpConn.RemoteAddr().String()] = tcpConn		go tcpPipe(tcpConn)	}}func tcpPipe(conn *net.TCPConn) {	ipStr := conn.RemoteAddr().String()	defer func() {		fmt.Println("disconnected :" + ipStr)		conn.Close()	}()	reader := bufio.NewReader(conn)	for {		message, err := reader.ReadString('\n')		if err != nil {			return		}		fmt.Println(conn.RemoteAddr().String() + ":" + string(message))		// 这里返回消息改为了广播		boradcastMessage(conn.RemoteAddr().String() + ":" + string(message))	}}func boradcastMessage(message string) {	b := []byte(message)	// 遍历所有客户端并发送消息	for _, conn := range ConnMap {		conn.Write(b)	}}

客户端完整代码如下:

client.go

package mainimport (	"bufio"	"fmt"	"net")func main() {	var tcpAddr *net.TCPAddr	tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:9999")	conn, _ := net.DialTCP("tcp", nil, tcpAddr)	defer conn.Close()	fmt.Println("connected!")	go onMessageRecived(conn)		// 控制台聊天功能加入	for {		var msg string		fmt.Scanln(&msg)		if msg == "quit" {			break		}		b := []byte(msg + "\n")		conn.Write(b)	}}func onMessageRecived(conn *net.TCPConn) {	reader := bufio.NewReader(conn)	for {		msg, err := reader.ReadString('\n')		fmt.Println(msg)		if err != nil {			quitSemaphore <- true			break		}	}}

最后分别编译server与client试试效果吧!

go build server.go

go build client.go

先启动server端, 然后新开两个个终端, 启动客户端, 在其中一个客户端里键入聊天信息后回车, 会发现另外一个客户端收到了刚刚发送的聊下天信息

完事大吉!

相关源码:

转载于:https://my.oschina.net/u/174175/blog/424051

你可能感兴趣的文章
我买了个阿里云服务器并在上面部署了一个项目
查看>>
《OpenStack云计算实战手册(第2版)》——1.6 配置角色
查看>>
Linux有问必答:如何在Debian下安装闭源软件包
查看>>
《ActionScript 3.0基础教程》——2.3 代码注释
查看>>
linux ubuntu/centos git 客户端编译安装升级
查看>>
JDK8 Fork/Join Work Stealing
查看>>
打包volley
查看>>
NavigationBar 和StatusBar同时消失出现
查看>>
Spring学习笔记之依赖的注解(2)
查看>>
软件工程之结尾篇
查看>>
Java和C#中的接口对比(有你不知道的东西)
查看>>
PHP连接数据库学习手册
查看>>
互联网协议入门(二)
查看>>
CentOS下MySQL数据库调优
查看>>
数据结构——图
查看>>
Shell学习笔记---数字递增总结
查看>>
JavaScript使用严格模式(Strict Mode)
查看>>
JavaScript权威设计--Window对象(简要学习笔记十三)
查看>>
NodeJs——(13)用连接池来控制mysql(入门版)
查看>>
modernizr框架之表单验证
查看>>