导读:本期聚焦于小伙伴创作的《如何用Golang实现TCP长连接服务?完整示例代码与核心逻辑解析》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Golang实现TCP长连接服务?完整示例代码与核心逻辑解析》有用,将其分享出去将是对创作者最好的鼓励。

Golang TCP长连接服务实现示例

在网络编程场景中,TCP长连接服务常用于需要服务端和客户端持续交互的场景,比如即时通讯、实时数据推送等。本文将通过一个完整的示例,讲解如何使用Golang实现基础的TCP长连接服务,包含服务端监听、客户端连接、消息收发以及连接保活等核心逻辑。

服务端实现

服务端的核心逻辑是监听指定端口,接收客户端连接,为每个连接启动独立的协程处理收发消息,同时实现心跳检测机制保证长连接的可用性。下面是完整的服务端代码:

package main

import (
	"bufio"
	"fmt"
	"net"
	"strings"
	"time"
)

// 心跳超时时间,超过该时间未收到客户端消息则断开连接
const heartbeatTimeout = 3 * time.Minute

// 处理单个客户端连接
func handleConn(conn net.Conn) {
	defer conn.Close()
	// 设置连接读取超时时间
	conn.SetReadDeadline(time.Now().Add(heartbeatTimeout))
	reader := bufio.NewReader(conn)
	remoteAddr := conn.RemoteAddr().String()
	fmt.Printf("客户端 %s 已连接\n", remoteAddr)

	for {
		// 读取客户端发送的消息,按换行符分割
		msg, err := reader.ReadString('\n')
		if err != nil {
			fmt.Printf("客户端 %s 连接断开: %v\n", remoteAddr, err)
			return
		}
		// 重置读取超时时间,说明客户端存活
		conn.SetReadDeadline(time.Now().Add(heartbeatTimeout))
		// 去除消息首尾的空白字符
		msg = strings.TrimSpace(msg)
		if msg == "" {
			continue
		}
		fmt.Printf("收到客户端 %s 消息: %s\n", remoteAddr, msg)

		// 处理消息,这里简单返回带时间戳的响应
		response := fmt.Sprintf("服务端已收到消息: %s, 时间: %s\n", msg, time.Now().Format("2006-01-02 15:04:05"))
		_, err = conn.Write([]byte(response))
		if err != nil {
			fmt.Printf("向客户端 %s 发送消息失败: %v\n", remoteAddr, err)
			return
		}
	}
}

func main() {
	// 监听本地8080端口
	listener, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Printf("启动监听失败: %v\n", err)
		return
	}
	defer listener.Close()
	fmt.Println("TCP长连接服务已启动,监听地址: 127.0.0.1:8080")

	for {
		// 阻塞等待客户端连接
		conn, err := listener.Accept()
		if err != nil {
			fmt.Printf("接收客户端连接失败: %v\n", err)
			continue
		}
		// 为每个连接启动独立的协程处理
		go handleConn(conn)
	}
}

上述代码中,服务端首先通过net.Listen监听127.0.0.1的8080端口,然后循环调用listener.Accept接收客户端连接。每收到一个连接,就启动一个独立的goroutine执行handleConn函数处理该连接。

handleConn函数中,我们设置了读取超时时间为3分钟,每当收到客户端消息时就重置超时时间,实现简单的心跳检测。如果超过3分钟没有收到客户端消息,读取操作会返回超时错误,服务端会自动关闭该连接。消息处理部分只是简单地将收到的消息带时间戳返回给客户端,实际场景中可以根据需求替换为业务处理逻辑。

客户端实现

客户端需要能够主动连接服务端,发送消息并接收服务端的响应,同时可以持续输入消息实现长连接交互。下面是完整的客户端代码:

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
	"time"
)

func main() {
	// 连接服务端
	conn, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Printf("连接服务端失败: %v\n", err)
		return
	}
	defer conn.Close()
	fmt.Println("已连接到服务端 127.0.0.1:8080,输入消息按回车发送,输入exit退出")

	// 启动协程接收服务端消息
	go func() {
		reader := bufio.NewReader(conn)
		for {
			msg, err := reader.ReadString('\n')
			if err != nil {
				fmt.Printf("接收服务端消息失败: %v\n", err)
				os.Exit(0)
				return
			}
			fmt.Printf("收到服务端响应: %s", strings.TrimSpace(msg))
		}
	}()

	// 主协程负责读取用户输入并发送消息
	inputReader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("请输入要发送的消息: ")
		input, err := inputReader.ReadString('\n')
		if err != nil {
			fmt.Printf("读取输入失败: %v\n", err)
			return
		}
		input = strings.TrimSpace(input)
		if input == "exit" {
			fmt.Println("准备退出客户端")
			return
		}
		if input == "" {
			continue
		}
		// 发送消息,末尾加上换行符方便服务端按行读取
		_, err = conn.Write([]byte(input + "\n"))
		if err != nil {
			fmt.Printf("发送消息失败: %v\n", err)
			return
		}
		// 稍微休眠避免消息发送过快
		time.Sleep(100 * time.Millisecond)
	}
}

客户端代码首先通过net.Dial连接服务端的127.0.0.1:8080地址,然后启动一个独立的goroutine用于接收服务端返回的响应消息,主协程则循环读取用户在终端的输入,将消息发送给服务端。

当用户输入"exit"时,客户端会主动关闭连接并退出。如果服务端主动断开连接,接收消息的goroutine会收到错误并打印提示,随后退出整个客户端程序。

运行测试

测试时可以先将服务端代码保存为server.go,客户端代码保存为client.go,然后分别打开两个终端执行以下命令:

  • 服务端终端:执行 go run server.go,启动后会看到"TCP长连接服务已启动"的提示
  • 客户端终端:执行 go run client.go,连接成功后会提示输入消息

在客户端终端输入任意消息按回车,就能看到服务端返回的带时间戳的响应。如果客户端超过3分钟没有发送消息,服务端会自动断开连接,客户端也会收到断开提示。

注意事项

上述示例是一个基础的长连接实现,实际生产环境中还需要考虑更多场景:

  • 连接断开后的重连机制,客户端可以在连接断开后尝试自动重连
  • 消息边界的处理,示例中使用换行符分割消息,实际场景可能需要更严谨的协议设计,比如固定长度消息、添加消息头标记长度等
  • 并发安全问题,如果多个goroutine操作同一个连接,需要加锁保证写入的原子性
  • 资源释放,确保连接断开后相关的资源都能正确回收,避免内存泄漏

GolangTCP长连接net包心跳检测goroutine修改时间:2026-05-23 16:11:38

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。