Golang如何监听TCP端口_Golang TCP端口监听与管理

22次阅读

net.Listen(“tcp”, “:8080”) 是唯一正确的起点;必须显式指定网络类型如 “tcp”、”tcp4” 或 “tcp6″,不可省略;”:8080″ 监听所有网卡,”127.0.0.1:8080″ 限本地调试,”tcp4″ 可规避双问题。

Golang如何监听TCP端口_Golang TCP端口监听与管理

net.Listen(“tcp”, “:8080”) 是唯一正确的起点

监听 TCP 端口必须显式指定网络类型为 "tcp"(或 "tcp4"/"tcp6"),不能只写 ":8080""localhost:8080" —— 否则会 panic:listen tcp: missing port in addressunknown network。冒号前留空(如 ":8080")表示监听所有可用网卡(等价于 "0.0.0.0:8080"),适合部署;若仅本地调试,建议用 "127.0.0.1:8080" 避免意外暴露。

  • net.Listen("tcp4", "127.0.0.1:8080") 更明确:强制 IPv4 + 仅回环,规避双绑定失败问题
  • 端口
  • 端口被占用时错误是 bind: address already in use,可先用 lsof -i :8080netstat -tuln | grep 8080 检查

listener.Accept() 必须配 goroutine,否则服务立即卡死

listener.Accept() 是阻塞调用,每次只返回一个 net.Conn;如果在主 goroutine 里直接处理(比如调用 conn.Read()),后续所有新连接都会排队等待——不是“慢”,而是彻底无法接入。这是新手最常踩的坑,现象是:第一个 telnet 连上了,第二个连不上,netstat 显示大量 SYN_RECV

  • 必须写成 go handleConnection(conn),让每个连接在独立 goroutine 中运行
  • handleConnection 函数开头务必 defer conn.Close(),否则连接泄漏,goroutine 积压后 OOM
  • 不要在循环里 breakreturn 错误,应 continue:监听器挂了才停,单个 Accept 失败不该终止整个服务

conn.Read() 不是一次读完一条消息,TCP 无边界是默认事实

TCP 是字节流,不是数据包。客户端调用三次 Write(),服务端一次 Read() 可能拿到全部拼接内容;也可能第一次只读到一半,第二次才收完——这叫“粘包”和“半包”。conn.Read(buf) 返回的是实际读到的字节数 n,不是 buf 长度。

  • 永远检查 err == io.EOF:这是客户端正常断开的信号,不是错误,应 clean exit
  • 避免假设 n > 0 就有有效数据;n == 0 虽少见,但可能表示对端静默关闭
  • 简单协议推荐 bufio.Scanner(按行)或 bufio.NewReader(带缓冲),比裸 Read() 更可靠
  • 生产环境务必设读写超时:conn.SetReadDeadline(),否则恶意客户端发半包会导致 goroutine 永久阻塞

监听器关闭 ≠ 连接自动结束,优雅退出需手动管理

调用 listener.Close() 只是让 Accept() 不再返回新连接,已建立的 conn 仍活跃。若此时进程直接退出,正在处理的连接会被强制中断,客户端可能收不到最后响应。

立即学习go语言免费学习笔记(深入)”;

  • 没有内置“等待所有连接结束”的机制;常见做法是用 sync.WaitGroup 计数活跃 goroutine
  • 更实用的是结合 context.WithTimeout 控制 Accept 循环,并在收到 SIGINT/SIGTERM 后关闭 listener,再 sleep 几秒让现有连接自然完成
  • 不要依赖 defer listener.Close() 做优雅关闭——它只在 main 函数退出时触发,而你往往需要提前关

真正难的从来不是写通第一行 net.Listen,而是想清楚:连接谁来关、超时怎么设、消息怎么分界、异常怎么归类。这些细节不写进代码里,上线后只会以连接堆积、CPU 爆高、日志满屏 EOF 的方式提醒你。

text=ZqhQzanResources