Go语言Socket编程:TCP服务端与客户端基础实例
本文详细介绍如何利用Go标准库中的 net 包快速实现基于TCP协议的Socket通信。包含服务端监听与连接处理、客户端连接建立与数据交互的完整代码,帮助你掌握Golang网络编程的基础流程。
Go语言Socket实现原理
在Go语言中,实现Socket通信主要依赖标准库 net。该库提供了高层抽象,使得开发者无需直接操作底层系统调用即可完成TCP连接的建立、数据传输与关闭。以下将通过一个最简单的回显服务示例,分别展示服务端和客户端的实现逻辑。
准备环境
- 安装Go环境:确保已安装Go 1.11或以上版本。
- 创建项目目录:建立两个文件
server.go(服务端)和client.go(客户端)。 - 端口约定:本示例使用端口
:6010作为通信端口,请确保该端口未被其他进程占用。
服务端实现:监听与连接处理
服务端的核心任务是监听指定端口,等待客户端连接,并在收到连接后启动协程独立处理该连接的数据收发。
第1步:编写服务端代码 server.go
服务端代码包含两个核心函数:main用于启动监听循环,handleConnection用于处理单个连接的生命周期。
package main
import (
"fmt"
"log"
"net"
"bufio"
)
// handleConnection 处理单个客户端连接
type ConnectionHandler func(conn net.Conn)
func handleConnection(conn net.Conn) {
// 创建BufferedReader读取数据
data, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
// 连接错误或关闭时记录日志
log.Printf("get client data error: %v", err)
return
}
// 打印接收到的数据
fmt.Printf("Received from client: %#v\n", data)
// 向客户端发送回复
_, err = fmt.Fprintf(conn, "hello client\n")
if err != nil {
log.Printf("send response error: %v", err)
}
// 关闭连接
conn.Close()
}
func main() {
// 监听TCP地址 :6010
ln, err := net.Listen("tcp", ":6010")
if err != nil {
panic(err)
}
defer ln.Close()
log.Println("Server listening on :6010")
for {
// 阻塞直到有连接到来
conn, err := ln.Accept()
if err != nil {
log.Fatal("accept connection error: ", err)
}
// 为每个新连接启动一个goroutine
go handleConnection(conn)
}
}
关键点说明:
net.Listen:绑定本地网络地址,返回Listener对象。ln.Accept():阻塞式接受连接,每成功一次返回一个新的net.Conn对象。go handleConnection(conn):使用Goroutine并发处理,避免单线程阻塞导致无法接受新连接。
第2步:启动服务端
在终端执行以下命令启动服务端:
go run server.go
此时程序将进入监听状态,等待客户端连接。
客户端实现:连接与数据交互
客户端负责主动发起TCP连接,发送请求消息,并接收服务端的响应。
第3步:编写客户端代码 client.go
package main
import (
"fmt"
"log"
"net"
"bufio"
)
func main() {
// 连接服务端 localhost:6010
conn, err := net.Dial("tcp", "localhost:6010")
if err != nil {
log.Fatal("dial error: ", err)
}
defer conn.Close()
// 发送消息给服务端
_, err = fmt.Fprintf(conn, "hello server\n")
if err != nil {
log.Fatal("send error: ", err)
}
// 读取服务端返回的数据
data, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
log.Fatal("read response error: ", err)
}
// 打印响应内容
fmt.Printf("Response from server: %#v\n", data)
}
关键点说明:
net.Dial:发起TCP连接,需指定网络类型(tcp/udp)和目标地址。fmt.Fprintf:向连接写入数据,注意以'\n'结尾以便服务端使用ReadString正确截断。bufio.NewReader(...).ReadString('\n'):按行读取,匹配服务端的发送格式。
第4步:测试通信
在另一个终端窗口执行以下命令运行客户端:
go run client.go
预期结果:
- 客户端控制台输出:
Response from server: "hello client\n" - 服务端控制台输出:
Received from client: "hello server\n"
排错与注意事项
常见问题排查
- connection refused (连接被拒绝)
- 原因:服务端未启动,或防火墙阻止了端口 6010。
- 解决:确认
go run server.go正在运行;检查系统防火墙规则。
- 原因:服务端使用
ReadString('\n')但客户端发送时未添加换行符。 - 解决:确保发送端字符串包含
\n,或使用ReadByte/ReadBytes自定义分隔符。
- 原因:目标地址格式错误或网络接口不可用。
- 解决:使用
localhost:6010或127.0.0.1:6010进行测试。
总结
通过以上步骤,我们成功使用Go语言的 net 包实现了最基础的TCP Socket通信。服务端利用Goroutine实现高并发连接处理,客户端完成请求-响应闭环。这是构建更复杂网络应用(如HTTP服务器、即时通讯系统等)的基石。
以上就是Go语言Socket编程基础教程:TCP服务端与客户端代码实例的详细内容,更多关于Golang网络编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









