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