go语言实现聊天服务器的示例代码

2020-01-28 13:02:00王旭

客户端:

支持断线重连;支持给特定其他客户端发信息


package main

import (
  "net"
  "fmt"
  "io"
  "os"
  "bufio"
  "sync"
  "time"
  "strings"
  "strconv"
)


var conn *net.Conn
var addrs []string

const (
  NORMAL_MESSAGE = iota
  LIST_MESSAGE
)

func read(conn2 *net.Conn){
  defer func() {
    fmt.Println("尝试重连")
    go connectServer()
  }()

  connect := *conn2
  buff := make([]byte, 20140)
  for {
    n, err := connect.Read(buff)
    if err != nil {
      if err == io.EOF{
        fmt.Println("结束")
        (*conn2).Close()
        conn = nil
        return
      } else{
        fmt.Println(err)
      }
    }

    msg := string(buff[:n])
    t, err := strconv.Atoi(string(msg[0]))
    msg = msg[1:]

    switch t {
    case NORMAL_MESSAGE:
      fmt.Print(msg)
      break
    case LIST_MESSAGE:
      // 解析客户端列表数据
      addrs = strings.Split(msg, "n")
      fmt.Println("已接收客户端列表。n")
      break
    default:
      fmt.Print(msg)
      break
    }
  }
}

func connectServer(){
  addr := "192.168.99.236:8080"
  fmt.Println("等待服务器开启中")
  conn2, err := net.Dial("tcp", addr)
  if err != nil {
    fmt.Print(err)
    fmt.Println("连接失败,10s后尝试")
    time.Sleep(10 * time.Second)
    go connectServer()
    return
  }

  fmt.Println("已连接")

  conn = &conn2
  go read(&conn2)
}

func send (){
  inputReader := bufio.NewReader(os.Stdout)
  for {
    input, err := inputReader.ReadString('n')
    if err != nil {
      if err == io.EOF{
        return
      } else{
        fmt.Println(err)
      }
    }

    if input == "lsn" {
      (*conn).Write([]byte(input))
      continue
    }

    msgs := strings.Split(input, "<-")
    if len(msgs) < 2 {
      fmt.Println("发送的姿势不正确,应该像这样 1<-给1号发送消息n")
      continue
    }

    index, err := strconv.Atoi(msgs[0])
    if err != nil {
      fmt.Println("发送的姿势不正确,应该像这样 1<-给1号发送消息n")
      continue
    }

    if len(addrs) <= index {
      fmt.Println("不存在第" + strconv.Itoa(index) + "个客户端n")
      continue
    }

    addr := addrs[index-1]

    input = addr + "<-" + strings.Join(msgs[1:], "<-")

    if nil != conn {
      (*conn).Write([]byte(input))
    }
  }
}

func main (){
  var wg sync.WaitGroup
  wg.Add(2)
  go connectServer()
  go send()
  wg.Wait()

  defer func() {
    if nil != conn {
      (*conn).Close()
    }
  }()
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易采站长站。