Golang编写一个基础的TCP服务器示例

发布时间 - 2026-01-05 00:00:00    点击率:
Go TCP服务器必须显式绑定0.0.0.0:8080才能外网访问,否则默认仅监听127.0.0.1;每个连接需用goroutine并发处理并defer关闭;读取须用bufio.Scanner或循环Read防止丢数据;关闭listener前须用WaitGroup等待活跃连接结束。

监听地址和端口必须显式绑定 0.0.0.0:8080127.0.0.1:8080

Go 的 net.Listen 不会默认监听所有接口,省略 IP 会导致只绑 127.0.0.1(本地回环),外部机器连不上。生产环境若需外网访问,得写成 "0.0.0.0:8080";仅本机调试可选 "127.0.0.1:8080"

常见错误现象:服务启动无报错,curl localhost:8080 成功,但换一台机器 telnet your-ip 8080 超时——八成是监听地址写成了 ":8080"(Go 会按平台默认解析,Linux 下常为 127.0.0.1)。

每个连接必须用 goroutine 并发处理,否则阻塞后续连接

listener.Accept() 是阻塞调用,返回一个 net.Conn。如果不启 goroutine,整个服务器就卡在当前连接的读写上,无法接受新连接。

  • 正确做法:对每个 conn 启动独立 goroutine,例如 go handleConnection(conn)
  • 错误写法:直接 handleConnection(conn) 同步执行,服务器退化成串行单连接
  • 注意:goroutine 内要 defer conn.Close(),否则连接泄漏

读取客户端数据要用 bufio.Scanner 或循环 conn.Read(),不能只调一次

TCP 是流式协议,conn.Read() 可能只读到部分数据,甚至 0 字节(比如对端关闭连接)。直接读一次就返回,会丢消息或提前退出。

推荐用 bufio.Scanner 简化按行读取:

scanner := bufio.NewScanner(conn)
for scanner.Scan() {
    line := scanner.Text()
    fmt.Fprintf(conn, "echo: %s\n", line)
}
if err := scanner.Err(); err != nil {
    log.Printf("scan error: %v", err)
}

如果需要处理二进制或自定义分隔符,就得手动循环 conn.Read(buf),检查返回字节数和 io.EOF

关闭监听器前要等所有活跃连接结束,否则 panic 或数据截断

listener.Close() 不会自动等待已 Accept 的连接处理完。如果主 goroutine 直接退出,正在运行的 handleConnection 可能被强制终止,导致 write on closed network connection 错误。

  • 简单场景:加个 signal.Notify 捕获 os.Interrupt,用 sync.WaitGroup 计数活跃连接
  • 关键点:Accept 前 wg.Add(1),goroutine 结束前 wg.Done(),关闭 listener 后 wg.Wait()
  • 忽略这点,SIGINT(Ctrl+C)后立刻退出,客户端可能收不到完整响应
TCP 服务器看似几行代码就能跑起来,但连接生命周期管理、并发安全、资源释放这三块最容易出隐蔽问题——尤其是没做连接计数就贸然关 listener,线上重启时丢请求很难排查。


# linux  # go  # golang  # 字节  # 端口  # curl  # ai  # EOF 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何为不同团队 ID 动态生成多个独立按钮  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  PHP 500报错的快速解决方法  Python文件流缓冲机制_IO性能解析【教程】  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  如何在橙子建站上传落地页?操作指南详解  详解阿里云nginx服务器多站点的配置  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  iOS发送验证码倒计时应用  个人摄影网站制作流程,摄影爱好者都去什么网站?  javascript读取文本节点方法小结  网站建设保证美观性,需要考虑的几点问题!  BootStrap整体框架之基础布局组件  如何快速上传建站程序避免常见错误?  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  微信小程序 五星评分(包括半颗星评分)实例代码  Laravel定时任务怎么设置_Laravel Crontab调度器配置  Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  php485函数参数是什么意思_php485各参数详细说明【介绍】  用yum安装MySQLdb模块的步骤方法  如何用西部建站助手快速创建专业网站?  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  智能起名网站制作软件有哪些,制作logo的软件?  制作电商网页,电商供应链怎么做?  如何快速搭建安全的FTP站点?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  如何用PHP工具快速搭建高效网站?  免费视频制作网站,更新又快又好的免费电影网站?  如何实现建站之星域名转发设置?  Laravel如何实现事件和监听器?(Event & Listener实战)  JavaScript Ajax实现异步通信  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  Laravel怎么使用Intervention Image库处理图片上传和缩放  C语言设计一个闪闪的圣诞树  Python制作简易注册登录系统  Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)  Laravel如何使用.env文件管理环境变量?(最佳实践)  在centOS 7安装mysql 5.7的详细教程  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  Laravel如何配置任务调度?(Cron Job示例)  常州企业网站制作公司,全国继续教育网怎么登录?  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  Laravel如何实现用户注册和登录?(Auth脚手架指南)  简单实现Android文件上传  Laravel如何发送邮件和通知_Laravel邮件与通知系统发送步骤  Bootstrap整体框架之JavaScript插件架构