Go网络编程|青训营笔记

65 阅读1分钟

这是我参与「第五届青训营 」笔记创作活动的第16天

TCP服务端可以接收多个客户端连接进行处理。服务端可以通过创建多个goroutine协程实现高并发处理连接请求。

go中通过net包实现网络编程。

服务端逻辑

  • 监听端口
  • 接收客户端的请求连接
  • 创建goroutine处理请求

服务端代码如下所示:

func process(conn net.Conn) {
   defer conn.Close() //关闭连接
   for {
      reader := bufio.NewReader(conn)  //数据缓冲区
      var buf [128]byte
      n, err := reader.Read(buf[:]) //读取数据
      if err != nil {
         fmt.Printf("read err %v", err)
         break
      }
      resv := string(buf[:n])
      
      //接收到消息后,可以替换成自己的处理逻辑
      fmt.Println("收到客户端发来消息", resv)
      
      //通过Write方法回复消息
      conn.Write([]byte(resv)) //发送数据
   }
}

func main() {
   // 服务器端开启端口
   listen, err := net.Listen("tcp", "127.0.0.1:9999")
   if err != nil {
      fmt.Println("listen failed, err:", err)
      return
   }
   for {
      conn, err := listen.Accept() // 建立连接
      if err != nil {
         fmt.Println("accept failed, err:", err)
         continue
      }
      go process(conn) // 启动一个goroutine处理连单独处理连接
   }
}

客户端的逻辑如下:

  • 建立与服务器的连接
  • 进行数据的发送与接收
  • 关闭连接

代码逻辑如下所示:

func main() {
   conn, err := net.Dial("tcp", "127.0.0.1:9999")
   if err != nil {
      fmt.Println("err :", err)
      return
   }
   defer conn.Close() // 关闭连接
   inputReader := bufio.NewReader(os.Stdin)
   for {
      input, _ := inputReader.ReadString('\n') // 读取用户输入
      inputInfo := strings.Trim(input, "\r\n")
      if strings.ToUpper(inputInfo) == "Q" { // 如果输入q就退出
         return
      }
      _, err = conn.Write([]byte(inputInfo)) // 发送数据
      if err != nil {
         return
      }
      buf := [512]byte{}
      n, err := conn.Read(buf[:])
      if err != nil {
         fmt.Println("recv failed, err:", err)
         return
      }
      fmt.Println(string(buf[:n]))
   }
}

运行server和client后,在client的控制台下输入消息如下所示:

image.png

服务器端会打印消息,然后恢复客户端,我们可以将打印的逻辑替换成自己处理消息的逻辑。

image.png

服务器回复的消息如下所示

image.png