• Go语言实践_实现一(客户端)对一(服务器端)聊天室


    一、目的

    使用Go语言实现一个服务器端与客户端的聊天室。

    软件:Goland,Go1.9

    代码仓库地址

    二、思路

    1,首先启动服务器端,使用listen_socket函数监听IP地址上的客户端连接;

    2,启动客户端,并向服务器端发送数据,发送结束后端口阻塞,等待服务器端的消息;

    3,服务器端接收到由客户端发送来的消息;

    4,服务器端向客户端发送数据,发送结束后;

    5,客户端接收到由服务器端发送来的消息,发送结束后端口阻塞,等待客户端的消息;

    6,重复步骤2-5;

    7,如果服务器端接收到由客户端发送来的“close"消息后,服务器端关闭与客户端的连接,继续等待下一个客户端的连接;

    8,客户端关闭,聊天结束。

    三、Go代码实现

    Sever端

    // One-to-one ChatRoom Sever
    package main
    
    import (
        "fmt"
        "net"
    )
    
    //var ConnMap map[string]*net.TCPConn
    
    func main() {
        listen_socket, err := net.Listen("tcp", "127.0.0.1:8000")  //打开监听接口
        if err != nil { //如果有错误
            fmt.Println("sever error")
        }
    
        defer listen_socket.Close()  //延迟服务器端关闭
        fmt.Println("sever is wating ....")
    
        for {
            conn, err := listen_socket.Accept()  //监听客户端的端口
            if err != nil {
                fmt.Println("conn fail ...")
            }
            fmt.Println("connect client successed")  //显示服务器端连接成功
    
            var msg string  //声明msg为字符串变量
    
            for {
                //开始接收客户端发过来的消息
                msg = ""  //字符串msg初始为空
                data := make([]byte, 255)  //创建并声明数据变量,为255位
                msg_read, err := conn.Read(data)  //接收由客户端发来的消息,字节赋值给msg_read,err为错误
                if msg_read == 0 || err != nil {  //如果读取的消息为0字节或者有错误
                    fmt.Println("err")
                }
    
                msg_read_str := string(data[0:msg_read])  //将msg_read_str的字节格式转化成字符串形式
                if msg_read_str == "close" {  //如果接收到的客户端消息为close
                    conn.Write([]byte("close"))
                    break
                }
                //fmt.Println(string(data[0:msg_read]))
                fmt.Println("client say: ", msg_read_str)  //接收客户端发来的信息
    
                fmt.Printf("say to client: ")  //提示向客户端要说的话
                fmt.Scan(&msg)  //输入服务器端要对客户端说的话
                //conn.Write([]byte("hello client
    "))
                //msg_write := []byte(msg)
                conn.Write([]byte(msg))  //把消息发送给客户端
                //此处造成服务器端的端口堵塞
            }
            fmt.Println("client Close
    ")
            conn.Close()  //关闭连接
        }
    
    }

    Client端

    // One-to-one ChatRoom Client
    package main
    
    import (
        "fmt"
        "net"
    )
    
    func main() {
        conn, err := net.Dial("tcp", "127.0.0.1:8000")
        if err != nil {
            fmt.Println("conn fail...")
        }
        defer conn.Close()
        fmt.Println("connect sever successed")
    
        var msg string  //声明msg为字符串变量
    
        for {
            msg = ""  //初始化msg为空值
            fmt.Printf("say to sever: ")
            fmt.Scan(&msg)  //输入客户端向服务器端要发送的消息
            //fmt.Println(msg)
            //msg_write := []byte(msg)
            //conn.Write(msg_write)
            conn.Write([]byte(msg))  //信息转化成字节流形式并向服务器端发送
            //此处造成客户端程序端口堵塞
            //fmt.Println([]byte(msg))
    
            //等待服务器端发送信息回来
            data := make([]byte, 255)
            msg_read, err := conn.Read(data)
            if msg_read == 0 || err != nil {
                fmt.Println("err")
            }
            msg_read_str := string(data[0:msg_read])
            if msg_read_str == "close" {
                conn.Write([]byte("close"))
                break
            }
    
            fmt.Println("sever say:", msg_read_str)
        }
        conn.Close()
    }

     

    四、小结

    • Write、Read、conn、Scan函数可造成程序的堵塞;
    • 网络中一般是用字节进行数据的传输,所以需要进行格式转换:发送时由字符串转字节;接收时由字节转字符串。
  • 相关阅读:
    (转)前端开发框架选型清单
    (转)关于java和web项目中的相对路径问题
    (转)phonegap 数据库详解
    (转)SQLite数据库增删改查操作
    (转)JS中innerHTML,innerText,value
    (转)js函数参数设置默认值
    (转)HTML5开发学习(2):本地存储之localStorage 、sessionStorage、globalStorage
    (转)HTML5开发学习(3):本地存储之Web Sql Database
    [笔记]普通平衡树(Splay)
    [笔记][题解]树链剖分&lgP3384
  • 原文地址:https://www.cnblogs.com/OctoptusLian/p/9401922.html
Copyright © 2020-2023  润新知