打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
聊天服务器/客户端实现

用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端, 然后新开两个个终端, 启动客户端, 在其中一个客户端里键入聊天信息后回车, 会发现另外一个客户端收到了刚刚发送的聊下天信息

完事大吉!

动手实践是学习 IT 技术最有效的方式! 开始实验
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【Go语言实战】(4) 简简单单的几十行代码实现 TCP 通信
CAS自定义客户端登录界面
golang之tcp自动重连
Go语言学习笔记(八)golang 操作 Redis & Mysql & RabbitMQ
Python
Extjs 文件上传和下载
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服