如何在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.SetReadDeadline或conn.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; ?>
】
相关推荐
- 手机php文件怎么变成mp4_安卓苹果打开php转
- c++如何使用std::bitset进行位图算法_
- php下载安装选zip还是msi格式_两种安装包对
- Win11怎么开启HDR模式_Windows 11
- 如何在Golang中使用闭包_封装变量与函数作用域
- Win11文件扩展名怎么显示_Win11查看文件后
- Python面向对象实战讲解_类与设计模式深入理解
- 如何在 Go 中创建包含 map 的 slice(
- php485函数怎么捕获异常_php485错误处理
- 如何诊断并终止卡死的 multiprocessin
- Python模块的__name__属性如何由导入方
- PHP cURL GET请求:正确设置请求头与身份
- php嵌入式多设备通信怎么实现_php同时管理多个
- Win11怎么设置多显示器任务栏 Win11扩展任
- 如何使用正则表达式提取以编号开头、后跟多个注解的完
- Windows10如何删除Windows.old_
- php控制舵机角度怎么调_php发送pwm信号控制
- php8.4如何配置ssl证书_php8.4htt
- PythonWeb前后端整合项目教程_FastAP
- Win11怎么把图标拖到任务栏_Win11固定应用
- 如何在Golang中使用内置函数_Golangle
- Windows怎样拦截WPS弹窗广告_Window
- php下载安装后swoole扩展怎么安装_异步框架
- 如何使用Golang构建基础消息队列模拟_Gola
- Windows 11怎么设置默认解压软件_Wind
- Win11怎么清理C盘系统日志_Win11清理系统
- php内存溢出怎么排查_php内存限制调试与优化方
- Windows11如何设置专注助手_Windows
- 如何使用Golang sync.Map实现并发安全
- php与c语言在嵌入式中有何区别_对比两者在硬件控
- Python高性能计算项目教程_NumPyCyth
- Windows11怎么用“记事本”自动换行与编码
- Win11怎么清理C盘OneDrive缓存_Win
- 如何在Golang中实现微服务服务拆分_Golan
- c++的static关键字有什么用 静态变量和静态
- Python lxml的etree和Element
- Python字符串处理进阶_切片方法解析【指导】
- 如何开启Windows的远程服务器管理工具(RSA
- windows如何备份注册表_windows导出和
- Win10 BitLocker加密教程 Win10
- Windows 10怎么录屏_Windows 10
- 如何在Golang中写入XML文件_生成符合规范的
- Win11 explorer.exe频繁崩溃_修复
- Win10怎么更改用户名 Win10修改账户名称操
- Windows10怎么查看硬件信息_Windows
- C++如何使用std::async进行异步编程?(
- Linux如何使用Curl发送请求_Linux下A
- 如何优化Golang Web性能_Golang H
- c++怎么使用类型萃取type_traits_c+
- Win11如何设置ipv6 Win11开启IPv6


QQ客服