Go语言学习笔记-聊天系统服务器与客户端

服务器

服务器就是有一个持续获取连接的动作,for循环实现,for循环开启处理消息的协程,处理消息的函数,接收消息并将消息写入缓冲信道。还有一个广播函数,用来将收到的消息发给所有与服务器连接的地址。

package main

import (
    "net"
    "os"
)

func main() {
    port := ":8080" //端口
    Start(port)

}
func Start(p string) {
    tcpAddr, err := net.ResolveTCPAddr("tcp", p)
    if err != nil {
        os.Exit(0)
        return
    }
    listener,err:= net.ListenTCP("tcp",tcpAddr)  //布置监听
    if err != nil {
        os.Exit(0)
        return
    }
    conns := make(map[string]net.Conn) //连接池,用来保存所有人的数据
    message := make(chan string,10)    //缓冲消息信道
    //时刻监听
    for{
      conn,err:= listener.AcceptTCP()  //返回网络连接
      if err!=nil{
          os.Exit(0)
          fmt.Println("Acception failed!")
          continue
      }
      conns[conn.RemoteAddr().String()] = conn  //将新连接存进map,键是他的远程地址
      go HandlerMessage(conn,message)  //启动接收信息协程
    }

}

//广播到所有conn  除了发出消息的
func BroadCast(conns map[string]net.Conn,mess chan int) {
    for {
        mess := <-messages  //读取信道信息
        for k, v := range conns {
            _, err := v.Write([]byte(mess))
            if err != nil {
                delete(conns, k)
                v.Close()
                continue
            }
            v.Write([]byte("BroadCast"))
        }
    }
}

//处理收的的消息
func HandlerMessage(conn net.Conn,mess chan string) {
    //for循环持续接收conn连接发来的信息
    for{
        buf := make([]byte,1024)
        length,err:=conn.Read(&buf)  //读取消息
        if err != nil {
            conn.Close()
            delete(cns, conn.RemoteAddr().String())
            break
        }
        mess<-string(buf[0:length])  //接收到的信息写入信道
        fmt.Println(string(buf[0:length]))
    }
  
}

客户端

客户端有一个开始的函数,用来连接服务器,开启协程,读取服务器发来的消息。发送消息的函数,接收输入消息后用conn.Write()发送消息。

package main

import (
    "fmt"
    "log"
    "net"
    "os"
)

func main() {
    Start(os.Args[1])  //os.Args是存储命令行的

}
func Start(addr string) {
    Tcpaddr, err := net.ResolveTCPAddr("tcp4", addr) //获取tcp
    if err != nil {
        log.Printf("Address error: %v\n", err)
        return
    }
    conn, err := net.DialTCP("tcp", nil, Tcpaddr) //连接服务器
    if err != nil {
        log.Printf("Dial to Server failed! %v\n", err)
        return
    }
    //启动发送消息协程
    go SendMessage(conn)
    buf := make([]byte, 1024)
    for {
        length, err := conn.Read(buf) //读取服务器发来的消息
        if err != nil {
            log.Printf("receive server's message failed! %v\n", err)
            conn.Close()   //关闭
            os.Exit(0)
        }
        fmt.Println(string(buf[0:length]))

    }
}
func SendMessage(conn net.Conn) {
    username := conn.LocalAddr().String()
    for {
        var in string
        fmt.Scanln(&in)   //接收输入的消息到in变量
        if len(in) > 0 {
            msg := username + "say:" + in
            _, err := conn.Write([]byte(msg))  //发送消息
            if err != nil {
                conn.Close()
                break
            }
        }
    }
}

你可能感兴趣的:(Go语言学习笔记-聊天系统服务器与客户端)