创建TCP服务器

package main

import (
   "encoding/base64"
   "fmt"
   "io"
   "net"
)

func serveClient(conn net.Conn) {
   // TCP四元组信息
   fmt.Printf("LocalAddr = %v \n", conn.LocalAddr().String())
   fmt.Printf("RemoteAddr = %v \n", conn.RemoteAddr().String())
   fmt.Printf("LocalAddr Network = %v \n", conn.LocalAddr().Network())
   fmt.Printf("RemoteAddr Network = %v \n", conn.RemoteAddr().Network())

   for {
      // 创建缓冲区保存客户端发送过来的消息,若消息长度超过缓冲区容量那么消息就会被拆分成几段发送
      var buffer = make([]byte, 1024)

      size, err := conn.Read(buffer) // 把客户端发送过来的消息放入缓冲区,返回值size为消息长度
      if err != nil {
         if err == io.EOF {
            fmt.Printf("客户端主动断开连接 \n")
         } else {
            fmt.Printf("读取客户端发送过来的消息失败:%+v \n", err.Error())
         }
         return
      } else {
         // 说明:为避免出现编码问题,客户端对消息进行了base64编码再发送消息,所以这里要解码
         var message []byte
         message, err = base64.StdEncoding.DecodeString(string(buffer[0:size]))
         if err != nil {
            fmt.Printf("base64解码失败:%+v \n", err.Error())
            return
         }

         fmt.Printf("收到客户端发送过来的消息:%v \n", string(message))
      }
   }
}

func main() {
   // 启动TCP服务器,服务端口号为9527
   listen, err := net.Listen("tcp", ":9527")
   if err != nil {
      panic("启动TCP服务器失败:" + err.Error())
   }

   // 停止TCP服务器
   defer func(listen net.Listener) {
      _ = listen.Close()
   }(listen)

   // 使用死循环监听客户端连接服务器
   for {
      var accept net.Conn
      accept, err = listen.Accept()
      if err != nil {
         panic("服务器无法接受客户端连接:" + err.Error())
      }

      fmt.Println("客户端与服务器连接成功")
      go serveClient(accept) // 启动协程为该客户端服务
   }
}

// ========== 输出过程·开始 ==========//
// 客户端与服务器连接成功
// LocalAddr = 192.168.1.2:9527
// RemoteAddr = 192.168.1.1:58923
// LocalAddr Network = tcp
// RemoteAddr Network = tcp
// 收到客户端发送过来的消息:PHP是世界上最好の语言
// 收到客户端发送过来的消息:从删库到跑路
// 客户端主动断开连接
// ========== 输出过程·结束 ==========//

// ========== base64编码/解码 ==========//
// PHP是世界上最好の语言 <===> UEhQ5piv5LiW55WM5LiK5pyA5aW944Gu6K+t6KiA
// 从删库到跑路 <===> 5LuO5Yig5bqT5Yiw6LeR6Lev

// ========== 总结 ==========//
// 1、可以使用网络调试助手(NetAssist)作为客户端。
// 2、TCP服务器最大连接数问题:一个TCP连接是由“源IP地址、目的IP地址、源端口、目的端口”四元组确定的,也就是代码中的
//    LocalAddr和RemoteAddr,由于服务器IP地址和TCP服务端口号是固定的,所以最大连接数为“客户端IP地址数×端口号数”,
//    不考虑IP地址分类和知名端口号,客户端IP地址数为2^32,端口号数为2^16,也就是单台TCP服务器最大连接数可以达到2^48。
//    但2^48只是理论上的最大值,实际上单台TCP服务器远远不能达到这个值,因为维护TCP连接需要占用内存和文件描述符,从硬
//    件配置和操作系统层面都限制了单台TCP服务器的最大连接数。

Copyright © 2024 码农人生. All Rights Reserved