0
点赞
收藏
分享

微信扫一扫

GO基于TCP开发一个简单的多人聊天室

五殳师兄 2022-03-20 阅读 69

1.server端代码如下:

    package main
    import (
        "fmt"
        "net"
    )
    //定义一个映射类型,用于存放每次请求的主机和Conn连接的对应关系
    var TcpHostMap map[string]net.Conn
    func HandleTcpReq(conn net.Conn) {
        for {
            ctx := make([]byte, 512)
            if _, err := conn.Read(ctx); err != nil {
                fmt.Println(conn.RemoteAddr().String() + "连接断开" + err.Error())
                break
            }
            //广播发送消息到所有客户端,除去当前的发送请求的客户端
            for k, v := range TcpHostMap {
                if conn.RemoteAddr().String() == v.RemoteAddr().String() {
                    continue
                }
                if _, err := v.Write(ctx); err != nil {
                    fmt.Println(k+"已经退出", err)
                    delete(TcpHostMap, k)
                }
            }
        }
        defer conn.Close()
    }
    func main() {
        Addr := "localhost:9191"
        Network := "tcp"
        TcpHostMap = make(map[string]net.Conn)
        listener, err := net.Listen(Network, Addr)
        if err != nil {
            fmt.Println(err)
            return
        }
        for {
            Conn, err := listener.Accept()
            if err == nil {
                fmt.Println("已建立连接" + Conn.RemoteAddr().String())
            } else {
                Conn.Close()
            }
            TcpHostMap[Conn.RemoteAddr().String()] = Conn
            fmt.Println(TcpHostMap)
            go HandleTcpReq(Conn)
        }
        defer listener.Close()
    }

2.客户端代码如下:

package main

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

func main() {
    var nickname, msg string
    Scanner := bufio.NewScanner(os.Stdin)
    Addr := "localhost:9191"
    Network := "tcp"
    Conn, err := net.Dial(Network, Addr)
    fmt.Print("请输入您在群聊中的昵称: ")
    fmt.Scanln(&nickname)
    if nickname != "" {
        fmt.Println("欢迎" + "<" + nickname + ">" + "加入群聊")
    }
    //通过go例程单独用于读取服务端响应数据
    go func() {
        for {
            ctx := make([]byte, 512)
            if _, err := Conn.Read(ctx); err != nil {
            fmt.Println("服务端连接异常: ", err)
            break
            }
            fmt.Println(string(ctx))
        }
        defer Conn.Close()
    }()
    for {
        Scanner.Scan() //此处建议用bufio中的scan,因fmt.Scan会将空格作为捕获分割
        msg = Scanner.Text()
        if msg == "exit" || msg == "quit" {
            fmt.Println("已断开连接")
            break
        }
        if msg != "" || msg != "\n" {
            _, err = Conn.Write([]byte("<" + nickname + ">:" + msg))
            if err != nil {
                fmt.Println("服务端连接异常: ", err)
                break
            }
        }
    }
    defer Conn.Close()
}

3.最终实现的效果如下:

image.png

举报

相关推荐

0 条评论