Go中的Tcp编程为什么总是能看到handle?
先搞懂:handle/handler 到底是什么意思?
- 英文本意:
- handle 作动词是 “处理、应对”,作名词是 “处理器、句柄”;
- handler 是 “处理者、处理器”(名词形式)。
- 编程中的含义:专门负责「处理某个特定事件 / 请求」的函数 / 结构体 / 接口。
在 TCP 编程中,这个 “事件 / 请求” 通常是:
- 新的客户端连接建立;
- 客户端发送过来的数据包;
- 连接断开 / 出错等异常情况。
TCP 编程的 “框架 / 业务” 分离逻辑
TCP 服务端的核心逻辑可以拆成两部分:
handle/handler 就是用来承载「业务逻辑层」的载体,框架层只负责 “调用” 它,不关心具体业务。
TCP 编程中 handler 的具体用法
TCP 服务端 – 处理单个连接
package main
import (
"bufio"
"fmt"
"net"
)
// 核心:定义处理单个 TCP 连接的 handler 函数,所有和业务相关的逻辑,
func handleConn(conn net.Conn) {
defer conn.Close()
fmt.Printf("客户端 %s 已连接\\n", conn.RemoteAddr())
// 读取客户端发送的数据(框架层)
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
msg := scanner.Text()
fmt.Printf("收到客户端 %s 的消息:%s\\n", conn.RemoteAddr(), msg)
// 业务逻辑层(handler 的核心职责)
response := "服务器已收到:" + msg
// 发送响应(框架层)
conn.Write([]byte(response + "\\n"))
}
fmt.Printf("客户端 %s 已断开连接\\n", conn.RemoteAddr())
}
func main() {
// 框架层:监听端口
listener, err := net.Listen("tcp", ":8888")
if err != nil {
fmt.Println("监听失败:", err)
return
}
defer listener.Close()
fmt.Println("TCP 服务端已启动,监听端口 8888")
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("接收连接失败:", err)
continue
}
go handleConn(conn)
}
}
定义成接口,让不同业务实现不同的 Handler,彻底解耦
package main
import (
"bufio"
"fmt"
"net"
)
// 定义 Handler 接口:所有业务处理器都要实现这个接口
type TCPHandler interface {
Handle(conn net.Conn) // 核心方法:处理连接
}
// 业务 1:echo 处理器(原样返回消息)
type EchoHandler struct{}
func (h *EchoHandler) Handle(conn net.Conn) {
defer conn.Close()
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
msg := scanner.Text()
conn.Write([]byte("Echo: " + msg + "\\n"))
}
}
// 业务 2:计算处理器(处理加法请求)
type CalcHandler struct{}
func (h *CalcHandler) Handle(conn net.Conn) {
defer conn.Close()
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
msg := scanner.Text()
// 模拟解析加法请求:比如 "10+20"
conn.Write([]byte("计算结果:30\\n")) // 简化逻辑
}
}
// 通用 TCP 服务端(框架层)
func StartTCPServer(addr string, handler TCPHandler) {
listener, _ := net.Listen("tcp", addr)
defer listener.Close()
fmt.Println("TCP 服务端启动:", addr)
for {
conn, _ := listener.Accept()
// 调用传入的 handler 处理连接(控制反转)
go handler.Handle(conn)
}
}
func main() {
// 启动 echo 服务(换业务只需要换 handler)
// StartTCPServer(":8888", &EchoHandler{})
// 启动计算服务
StartTCPServer(":8888", &CalcHandler{})
}




