如何在Golang中搭建TCP服务器_Golang net Listen与Accept方法

技术百科 P粉602998670 发布时间:2026-01-23 浏览:
Go中Listen后必须循环调用Accept并配合goroutine处理并发连接,否则仅能处理首个连接;每个conn需设读写超时并显式关闭以防fd泄漏。

Listen 之后必须调用 Accept 才能接收连接

Go 的 net.Listen 只是创建监听套接字并绑定地址,它不阻塞、也不处理任何客户端连接;真正等待并获取新连接的是 Accept。常见错误是只调用 Listen 就结束程序,结果服务看似“启动了”,但根本收不到请求。

  • Listen 返回 net.Listener 接口,需持续调用其 Accept() 方法
  • Accept() 是阻塞调用,返回 net.Conn(代表一个具体连接)和可能的错误
  • 若不循环调用 Accept,服务器只能处理第一个连接就退出

Accept 必须配合 goroutine 处理并发连接

每个 Accept 返回的 net.Conn 是单次连接,读写操作(如 Read/Write)也是阻塞的。如果在主线程里同步处理,后续连接会排队等待——这不是“服务器没响应”,而是逻辑卡死在上一个连接的 I/O 上。

  • 典型模式:主 goroutine 循环 Accept,每拿到一个 conn 就起一个新 goroutine 处理
  • 不加 goroutine 的写法会导致吞吐量归零,尤其在连接持续发送数据时
  • 注意关闭 conn:应在处理 goroutine 结束前调用 conn.Close(),否则 fd 泄漏
listener, err := net.Listen("tcp", ":8080")
if err != nil {
    log.Fatal(err)
}
defer listener.Close()

for {

conn, err := listener.Accept() if err != nil { log.Println("Accept error:", err) continue // 不要直接 break,避免整个服务中断 } go func(c net.Conn) { defer c.Close() buf := make([]byte, 1024) n, _ := c.Read(buf) c.Write(buf[:n]) }(conn) }

Listen 地址字符串格式与端口占用问题

net.Listen("tcp", addr)addr 必须是形如 "host:port" 的字符串。本地监听常用 ":8080"(等价于 "localhost:8080"),但要注意:

  • ":8080" 监听所有 IPv4/IPv6 地址,"127.0.0.1:8080" 仅限 IPv4 回环
  • 若端口已被占用,Listen 返回 *net.OpError,错误信息含 "bind: address already in use"
  • Linux/macOS 下可复用端口需设置 SO_REUSEADDR,Go 默认不启用;可通过 net.ListenConfig 配置 Control 函数实现

Accept 返回的 Conn 需要显式超时控制

net.Conn 默认无读写超时,一旦客户端异常断连或发半包,Read 可能永远阻塞。不能依赖 listener.SetDeadline(它不存在),而要对每个 conn 单独设。

  • 使用 conn.SetReadDeadlineconn.SetDeadline 设置绝对时间点
  • 推荐用 conn.SetReadTimeout(相对时长),更直观
  • 超时后 Read 返回 io.EOF 或带 net.ErrTimeout 的错误,需检查并退出处理 goroutine

实际部署中,最易被忽略的是连接超时和资源清理——没有超时,几百个空闲连接就能拖垮服务;没有 defer conn.Close(),文件描述符耗尽后 Accept 会开始报 "too many open files"


# 的是  # 就能  # 也不  # 第一个  # 它不  # 已被  # 要对  # 客户端  # mac  # linux  # 端口  # go  # golang  # 循环  # 并发  # macos  # cos  # 字符串  # 接口  # 线程  # 这不是  # 主线程  # ipv6  # 应在  # EOF 


相关栏目: <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 AI推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 SEO优化<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 技术百科<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 谷歌推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 百度推广<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 网络营销<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 案例网站<?muma echo $count; ?> 】 <?muma $count = M('archives')->where(['typeid'=>$field['id']])->count(); ?> 【 精选文章<?muma echo $count; ?>

相关推荐

在线咨询

点击这里给我发消息QQ客服

在线咨询

免费通话

24h咨询:4006964355


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部