加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang实现简单tcp服务器03 -- 文本广播式聊天服务器/客户端

发布时间:2020-12-16 18:42:30 所属栏目:大数据 来源:网络整理
导读:用Golang实现 文本广播式聊天服务器/客户端 本节,我们将一步一步的把上一节完成的echo服务器/客户端改造成一个文本信息的聊天室 服务端的改动 服务器为了实现聊天信息的群体广播,需要记录所有连接到服务器的客户端信息,所以,我们需要添加一个集合来保存所有

用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 main

import (
	"bufio"
	"fmt"
	"net"
)

// 用来记录所有的客户端连接
var ConnMap map[string]*net.TCPConn

func 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 main

import (
	"bufio"
	"fmt"
	"net"
)

func main() {
	var tcpAddr *net.TCPAddr
	tcpAddr,"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://git.oschina.net/victoriest/go-simple-tcp-server.git

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读