欢迎光临
我们一直在努力

Go中的Tcp编程为什么总是能看到handle?

Go中的Tcp编程为什么总是能看到handle?

先搞懂:handle/handler 到底是什么意思?

  • 英文本意:
    • handle 作动词是 “处理、应对”,作名词是 “处理器、句柄”;
    • handler 是 “处理者、处理器”(名词形式)。
  • 编程中的含义:专门负责「处理某个特定事件 / 请求」的函数 / 结构体 / 接口。

在 TCP 编程中,这个 “事件 / 请求” 通常是:

  • 新的客户端连接建立;
  • 客户端发送过来的数据包;
  • 连接断开 / 出错等异常情况。

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{})
    }


    四、为什么偏偏是 handle/handler?

  • 语义精准:handler 直接点明 “这个东西是用来处理某个事件的”,比随便起个名字(比如 process/do)更清晰;
  • 行业通用:不只是 Go 的 TCP 编程,Java 的 Netty、Python 的 Socket 编程、前端的事件处理(event handler)都用这个命名 —— 属于程序员的 “通用语言”,看到就知道是 “处理器”;
  • 职责明确:看到 handleConn/TCPHandler,立刻能区分 “这是处理连接的业务逻辑”,和 “监听端口、读写数据的框架逻辑” 划清界限;
  • 符合 Go 语言习惯:Go 标准库中大量使用 Handler 命名(比如 http.Handler),TCP 编程自然沿用这个习惯,保持一致性。
  • 赞(0)
    未经允许不得转载:171主机测评 » Go中的Tcp编程为什么总是能看到handle?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址