zoukankan      html  css  js  c++  java
  • golang 简易聊天

    client.go
    ------------------------------
    package main
    
    import (
        "net"
        "fmt"
        "bufio"
        "echo/codec"
        "time"
    )
    
    var quitSemaphore chan bool
    
    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) //接收消息
        go sendMessage(conn) //发送消息
        <-quitSemaphore
    }
    
    // 发送消息
    func sendMessage(conn *net.TCPConn)  {
        //发送消息
        for{
            time.Sleep(1 * time.Second)
            var msg string
            fmt.Scanln(&msg)
            if msg == "quit"{
                quitSemaphore <- true
                break
            }
            //lk
            //b :=[]byte(msg +"
    ")
            //处理加密
            b ,_ := codec.Encode(msg+"
    ")
            conn.Write(b)
        }
    }
    server.go
    -----------------------------
    package main
    
    import (
        "bufio"
        "fmt"
        "net"
        "echo/codec"
    )
    
    // 用来记录所有的客户端连接
    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) //开启tcp 服务
        //退出时关闭
        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 :=codec.Decode(reader)//reader.ReadString('
    ')
            if err != nil {
                return
            }
            fmt.Println(string(message))
            //这里返回消息改为广播
            boradcastMessage(conn.RemoteAddr().String()+":"+string(message))
        }
    }
    //广播给其它 
    func boradcastMessage(message string)  {
        //遍历所有客户端并发消息
        for _,conn :=range ConnMap{
            b,err :=codec.Encode(message)
            if err != nil {
                continue
            }
            conn.Write(b)
        }
    }
    
    
    codec.go
    ------------------------
    package codec
    
    import (
        "bytes"
        "encoding/binary"
        "bufio"
    )
    
    func Encode(message string) ([]byte, error) {
        // 读取消息的长度
        var length int32 = int32(len(message))
        var pkg *bytes.Buffer = new(bytes.Buffer)
        // 写入消息头
        err := binary.Write(pkg, binary.LittleEndian, length)
        if err != nil {
            return nil, err
        }
        // 写入消息实体
        err = binary.Write(pkg, binary.LittleEndian, []byte(message))
        if err != nil {
            return nil, err
        }
    
        return pkg.Bytes(), nil
    }
    
    func Decode(reader *bufio.Reader) (string, error) {
        // 读取消息的长度
        lengthByte, _ := reader.Peek(4)
        lengthBuff := bytes.NewBuffer(lengthByte)
        var length int32
        err := binary.Read(lengthBuff, binary.LittleEndian, &length)
        if err != nil {
            return "", err
        }
        if int32(reader.Buffered()) < length+4 {
            return "", err
        }
    
        // 读取消息真正的内容
        pack := make([]byte, int(4+length))
        _, err = reader.Read(pack)
        if err != nil {
            return "", err
        }
        return string(pack[4:]), nil
    }
    func onMessageRecived(conn *net.TCPConn)  {
        reader :=bufio.NewReader(conn)
        for {
            //解密
            msg,err := codec.Decode(reader)//reader.ReadString('
    ')
            fmt.Println(msg)
            if err !=nil {
                quitSemaphore <- true
                break
            }
        }
    }
  • 相关阅读:
    mysql 内联接、左联接、右联接、完全联接、交叉联接 区别
    JS 时间字符串与时间戳之间的转换
    MySQL性能优化的最佳20条经验
    ++i 与 i++ 的区别
    === 与 == 区别
    SC命令创建和删除windows服务
    杂记
    linux 文件编程
    u-boot 启动过程
    简单冒泡法
  • 原文地址:https://www.cnblogs.com/jackluo/p/5378781.html
Copyright © 2011-2022 走看看