当前位置: 首页 > news >正文

Go语言实战案例:TCP服务器与客户端通信

在网络编程中,TCP 是最常见的传输协议之一。Go 提供了 net 包,可以方便地实现 TCP 服务器与客户端通信。本篇将以实战形式演示如何用 Go 创建一个 TCP 服务器,并让多个客户端与之通信。


一、实战背景

相比 HTTP 请求响应,TCP 通信更底层、更灵活,适合用在:

  • • 游戏服务器
  • • 实时聊天程序
  • • 长连接服务
  • • 数据同步服务

本案例将实现一个简单的 TCP 聊天服务器:

  • • 支持多个客户端连接
  • • 客户端发送内容,服务器打印并回应
  • • 演示并发连接处理

二、实战目标

构建一个简单的 TCP 网络程序,包含两个组件:

  1. 1. TCP服务器
    • • 启动监听指定端口
    • • 接收多个客户端连接
    • • 每条连接独立处理,读取数据并回复
  2. 2. TCP客户端
    • • 连接到服务器
    • • 从终端输入消息并发送
    • • 接收服务器返回的响应

三、完整代码实现

1. TCP服务器代码(server.go)

package mainimport ("bufio""fmt""net""strings"
)func handleConnection(conn net.Conn) {defer conn.Close()addr := conn.RemoteAddr().String()fmt.Println("客户端连接:", addr)reader := bufio.NewReader(conn)for {data, err := reader.ReadString('\n')if err != nil {fmt.Println("客户端断开:", addr)return}msg := strings.TrimSpace(data)fmt.Printf("收到[%s]: %s\n", addr, msg)// 回复消息response := fmt.Sprintf("服务端收到: %s\n", msg)conn.Write([]byte(response))}
}func main() {listener, err := net.Listen("tcp", ":8888")if err != nil {fmt.Println("启动失败:", err)return}defer listener.Close()fmt.Println("TCP服务器已启动,监听端口 8888...")for {conn, err := listener.Accept()if err != nil {fmt.Println("连接失败:", err)continue}go handleConnection(conn)}
}

2. TCP客户端代码(client.go)

package mainimport ("bufio""fmt""net""os""strings"
)func main() {conn, err := net.Dial("tcp", "127.0.0.1:8888")if err != nil {fmt.Println("连接服务器失败:", err)return}defer conn.Close()fmt.Println("已连接到服务器。请输入消息,输入 exit 退出:")reader := bufio.NewReader(os.Stdin)for {fmt.Print(">> ")input, _ := reader.ReadString('\n')input = strings.TrimSpace(input)if input == "exit" {fmt.Println("断开连接")return}// 发送消息conn.Write([]byte(input + "\n"))// 接收服务器响应response, _ := bufio.NewReader(conn).ReadString('\n')fmt.Println("服务器响应:", strings.TrimSpace(response))}
}

四、运行方式

启动服务器

go run server.go

输出示例:

TCP服务器已启动,监听端口 8888...

启动客户端(多个终端可同时运行)

go run client.go

输入消息:

>> hello
服务器响应: 服务端收到: hello

服务器端输出:

客户端连接: 127.0.0.1:53458
收到[127.0.0.1:53458]: hello

五、关键技术点解析

1. net.Listen("tcp", ":8888")

用于监听本地 8888 端口,协议为 TCP。支持 IPv4、IPv6。


2. listener.Accept()

阻塞方法,等待客户端连接。每当有新连接,就返回一个 net.Conn


3. 并发处理连接

使用 go handleConnection(conn),每个客户端独立处理,避免阻塞。


4. bufio.NewReader(conn).ReadString('\n')

按行读取客户端发送内容。注意客户端必须发送换行(\n)结束,否则会阻塞。


5. 客户端 net.Dial

客户端使用 net.Dial("tcp", addr) 建立连接。注意服务端地址和端口应正确。


六、可扩展方向

方向实现建议
广播机制使用 map[conn]bool 存储连接,广播消息
客户端昵称每个连接输入昵称,并用于标识消息来源
心跳检测定期向客户端发送 ping,判断是否掉线
JSON 协议使用结构化数据通讯
TLS 加密通信使用 crypto/tls 加密 TCP 通道
多线程聊天室支持多房间并发聊天

七、小结

通过本案例你掌握了:

✅ 如何编写基本的 TCP 服务端和客户端
✅ 使用 Goroutine 实现并发连接处理
✅ 使用 bufio.Reader/Writer 实现按行读写
✅ 终端交互式发送/接收消息

这是构建分布式系统、即时通讯、远程控制服务的基础能力。


http://www.lryc.cn/news/608944.html

相关文章:

  • 案例介绍|JSON数据格式的转换|pyecharts模块简介
  • Kafka——怎么重设消费者组位移?
  • 构建企业级Web应用:AWS全栈架构深度解析
  • AtCoder Beginner Contest 417
  • [硬件电路-147]:模拟电路 - DC/DC电压的三种架构:升压(Boost)、降压(Buck)或升降压(Buck-Boost)
  • 跨语言模型中的翻译任务:XLM-RoBERTa在翻译任务中的应用
  • 界面规范4-按钮
  • IntelliJ IDEA开发编辑器摸鱼看股票数据
  • Parcel 使用详解:零配置的前端打包工具
  • 关于车位引导及汽车乘梯解决方案的专业性、系统性、可落地性强的综合设计方案与技术实现说明,旨在为现代智慧停车楼提供高效、安全、智能的停车体验。
  • electron-多线程
  • 嵌入式——数据结构:单向链表的函数创建
  • 常见的深度学习模块/操作中的维度约定(系统性总结)
  • Docker-03.快速入门-部署MySQL
  • 介绍JAVA语言、介绍greenfoot 工具
  • 北邮:LLM强化学习架构Graph-R1
  • 【机器学习】线性回归算法详解:线性回归、岭回归、Lasso回归与Elastic Net
  • 02.Redis 安装
  • 13.Redis 的级联复制
  • kafka与其他消息队列(如 RabbitMQ, ActiveMQ)相比,有什么优缺点?
  • 《深入浅出RabbitMQ:从零基础到面试通关》
  • RabbitMQ面试精讲 Day 10:消息追踪与幂等性保证
  • 《软件测试与质量控制》实验报告三 系统功能测试
  • Flutter开发 dart异步
  • Spring lookup-method实现原理深度解析
  • [spring-cloud: 服务注册]-源码解析
  • 【Linux】linux基础开发工具(三) 版本控制器Git、调试器 - gdb/cgdb使用、一些实用的调试技巧
  • graph TD的规则
  • zookeeper持久化和恢复原理
  • 大模型智能体(Agent)技术全景:架构演进、协作范式与应用前沿