用Go写一个简单的TCP服务器
在维护服务器时,经常需要处理自定义协议或调试底层通信。Go语言因为语法简洁、并发模型优秀,成了不少运维和后端开发人员的首选。比如你手上有个小需求:监控某个内部服务的状态,又不想引入复杂的框架,这时候用Go写个轻量级TCP服务就特别合适。
下面这个例子实现了一个基础的TCP回声服务器——客户端发什么,服务器就原样返回什么。
package main
import (
"bufio"
"fmt"
"log"
"net"
)
func main() {
listener, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
fmt.Println("服务器已启动,监听 8080 端口...")
for {
conn, err := listener.Accept()
if err != nil {
log.Print(err)
continue
}
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
data := scanner.Text()
fmt.Printf("收到消息:%s\n", data)
_, _ = conn.Write([]byte(data + "\n"))
}
}代码说明
net.Listen("tcp", ":8080") 启动一个TCP监听,绑定在本机8080端口。Accept() 接受每一个新连接,然后用 go handleConnection(conn) 开启协程处理,这样不会阻塞后续连接。
使用 bufio.Scanner 读取客户端发来的每行数据,再通过 conn.Write 回写回去。虽然简单,但已经具备了基本的网络交互能力。
写个客户端测试一下
光有服务器还不够,来个对应的客户端验证功能。
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
go func() {
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
fmt.Println("[服务器]", scanner.Text())
}
}()
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
msg := input.Text()
_, _ = conn.Write([]byte(msg + "\n"))
}
}运行服务器程序后,再启动客户端,你在终端输入什么,服务器就会返回什么,就像两个人聊天一样。这种模式常用于调试设备心跳、协议格式校验等场景。
实际运维中的用途
别小看这个回声服务。你可以把它改造成健康检查接口,让负载均衡器定时连接某个端口,只要能通且返回预期内容就算服务正常。也可以加点日志,记录连接来源,辅助排查异常IP。
更进一步,把文本处理逻辑换成解析二进制协议,就能对接物联网设备或者老旧系统。Go的 bytes 包和 encoding/binary 配合使用,处理字节序问题也很方便。
遇到大量并发连接也不用担心,Go的goroutine开销小,几万个连接也能轻松应对。比用Python多线程或Node.js事件循环更容易掌控。
部署时编译成单个二进制文件,丢到服务器上直接运行,不依赖运行时环境,特别适合做边缘服务或临时诊断工具。