Golang TCP长连接服务实现示例

Go语言通过net包实现TCP长连接服务,用于即时通讯等场景。首先使用net.Listen监听端口,Accept接受连接并为每个客户端启动goroutine处理读写。在handleConnection中,开启读协程接收数据,通过SetReadDeadline设置读超时实现心跳检测,收到消息后重置超时,若接收到”ping”则回复”pong”。主协程等待done信号关闭连接。客户端示例通过Dial连接服务器,循环发送消息并读取回显,验证通信正常。整体结构包含连接管理、读写分离与心跳机制,具备扩展性,可结合context、协议编码等提升生产环境稳定性。

golang tcp长连接服务实现示例

在Go语言中实现TCP长连接服务,通常用于即时通讯、设备上报、心跳维持等场景。核心是通过net包监听TCP连接,为每个客户端维护一个持久连接,并支持读写分离、心跳检测、并发安全处理。下面是一个简洁但完整的TCP长连接服务示例。

1. 基础TCP服务器结构

使用net.Listen创建监听,接受客户端连接并为每个连接启动独立的goroutine处理数据收发。

package main

import ("fmt""log""net")

func main() {listener, err := net.Listen("tcp", ":8080")if err != nil {log.Fatal("监听端口失败:", err)}defer listener.Close()fmt.Println("TCP服务器启动,监听 :8080")

for {    conn, err := listener.Accept()    if err != nil {        log.Println("接受连接失败:", err)        continue    }    go handleConnection(conn)}

}

2. 处理长连接的读写逻辑

每个连接开启两个goroutine:一个负责读取客户端数据,另一个可选地处理消息发送。使用sync.Mutex或通道协调状态。

func handleConnection(conn net.Conn) {    defer conn.Close()    clientIP := conn.RemoteAddr().String()    fmt.Printf("客户端 %s 已连接n", clientIP)
// 模拟存储连接状态(实际可用map+锁或context管理)done := make(chan bool)// 读协程go func() {    buffer := make([]byte, 1024)    for {        n, err := conn.Read(buffer)        if err != nil {            fmt.Printf("客户端 %s 断开: %vn", clientIP, err)            done <- true            return        }        msg := string(buffer[:n])        fmt.Printf("来自 %s 的消息: %sn", clientIP, msg)        // 回显消息(可替换为业务逻辑)        conn.Write([]byte("echo: " + msg))    }}()// 可扩展:写协程通过channel接收消息主动下发<-done

}

3. 添加心跳机制保活

TCP连接可能因网络中断静默断开,需加入心跳检测。常见做法是设定读超时,或让客户端定期发送ping。

立即学习“go语言免费学习笔记(深入)”;

import (    "time")

func handleConnection(conn net.Conn) {defer conn.Close()clientIP := conn.RemoteAddr().String()fmt.Printf("客户端 %s 已连接n", clientIP)

conn.SetReadDeadline(time.Now().Add(30 * time.Second)) // 初始超时done := make(chan bool)go func() {    buffer := make([]byte, 1024)    for {        n, err := conn.Read(buffer)        if err != nil {            done <- true            return        }        msg := string(buffer[:n])        fmt.Printf("收到: %sn", msg)        // 收到消息重置超时时间        conn.SetReadDeadline(time.Now().Add(30 * time.Second))        // 简单协议判断是否为心跳        if msg == "ping" {            conn.Write([]byte("pong"))        } else {            conn.Write([]byte("echo: " + msg))        }    }}()// 超时或异常退出<-donefmt.Printf("连接 %s 关闭n", clientIP)

}

4. 客户端测试示例

使用简单客户端连接并发送数据验证服务稳定性。

package main

import ("fmt""net""time")

func main() {conn, _ := net.Dial("tcp", "127.0.0.1:8080")defer conn.Close()

for i := 0; i < 5; i++ {    msg := fmt.Sprintf("hello %d", i)    conn.Write([]byte(msg))    buf := make([]byte, 1024)    n, _ := conn.Read(buf)    fmt.Println("回显:", string(buf[:n]))    time.Sleep(2 * time.Second)}// 发送心跳conn.Write([]byte("ping"))buf := make([]byte, 1024)n, _ := conn.Read(buf)fmt.Println("心跳响应:", string(buf[:n]))

}

基本上就这些。这个示例展示了如何用Go构建一个基础的TCP长连接服务,包含连接管理、读写分离和心跳机制。实际生产环境中可结合context取消、连接池、协议编码(如protobuf)、日志监控等进一步增强健壮性。

以上就是Golang TCP长连接服务实现示例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1413483.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月16日 07:16:14
下一篇 2025年12月16日 07:16:31

相关推荐

  • 如何在Golang中读取和写入JSON文件

    在Golang中读写JSON文件需使用encoding/json和os包。2. 定义字段首字母大写的结构体并用json标签映射键名。3. 用os.Open配合json.Decoder读取文件内容到结构体。4. 用os.Create结合json.Encoder将结构体写入文件并可格式化输出。5. 处理…

    2025年12月16日
    000
  • 云原生应用资源限制与配额管理实践

    合理配置Kubernetes资源请求与限制、设置命名空间级配额和默认策略,并结合监控调优,可有效保障应用稳定性和资源利用率。 在云原生环境中,合理管理应用的资源使用是保障系统稳定性、提升资源利用率的关键。Kubernetes 作为主流的云原生编排平台,提供了资源限制(Resource Limits)…

    2025年12月16日
    000
  • Golang函数返回指针和返回slice有什么区别

    返回指针传递地址,避免拷贝大对象并支持共享状态;返回slice虽为值类型,但内部含指针,可共享底层数组,适合表示数据集合。 在Go语言中,函数返回指针和返回slice是两种不同的设计选择,它们在内存管理、性能、语义和使用方式上存在明显区别。理解这些差异有助于写出更安全、高效的代码。 返回指针对应的是…

    2025年12月16日
    000
  • Golang goroutine与channel调试技巧

    使用go run -race检测数据竞争,结合runtime.NumGoroutine监控协程数量,通过pprof分析阻塞调用栈,利用select超时避免永久阻塞,有效排查goroutine泄漏、死锁和数据竞争问题。 Go语言的goroutine和channel是并发编程的核心,但它们也带来了调试上…

    2025年12月16日
    000
  • Golang如何在MacOS中安装Go SDK

    推荐使用官方安装包或Homebrew安装Go SDK。首先访问Go官网下载macOS的.pkg安装包并按向导安装,完成后在终端执行go version验证版本;或使用Homebrew直接运行brew install go安装并验证。安装后建议配置GOPATH和PATH环境变量,编辑~/.zshrc文…

    2025年12月16日
    000
  • 字符串拼接与处理在Golang中怎么做

    strings.Join适用于已知切片的连接,性能好;2. strings.Builder适合循环中大量拼接,通过预分配内存提升效率。 在Go语言中,字符串是不可变的,因此拼接和处理需要借助特定方法来高效完成。直接使用+操作符虽然简单,但在频繁操作时性能较差。以下是几种常用的字符串拼接与处理方式。 …

    2025年12月16日
    000
  • 如何在Golang中实现组合模式管理对象树

    组合模式通过统一接口管理单个对象和对象集合,适用于文件系统等层级结构。定义Component接口包含Print和GetSize方法,使叶节点(如File)和容器节点(如Directory)行为一致。File实现接口直接返回自身信息,Directory则维护子组件列表并递归调用其方法。构建树时可逐层添…

    2025年12月16日
    000
  • Golang如何测试并发安全函数

    答案是使用go test -race结合sync.WaitGroup模拟多协程并发访问,验证数据一致性和竞态条件。通过启动多个goroutine对共享资源进行操作,利用WaitGroup同步等待所有操作完成,并借助-race检测是否存在内存竞争,若存在则测试失败。示例中对SafeCounter的In…

    2025年12月16日
    000
  • Golang如何捕获并记录程序运行时错误

    Go语言通过defer和recover捕获panic,结合日志与堆栈追踪实现错误处理。在关键函数或goroutine入口使用defer注册recover,可防止程序崩溃并记录上下文信息。需为每个goroutine单独设置recover,避免主协程无法捕获子协程异常。推荐使用runtime.Stack…

    2025年12月16日
    000
  • Golang环境搭建如何检查安装是否成功

    答案是通过版本检查、环境变量验证和程序运行测试确认Golang环境安装成功。依次执行go version查看版本,go env检查GOROOT和GOPATH配置,编写hello.go文件并使用go run运行输出Hello, Go!,再用go build生成可执行文件并运行验证编译功能,全部通过则环…

    2025年12月16日
    000
  • 如何在Golang中实现反射调用函数

    反射调用函数需先通过reflect.ValueOf获取函数值,再将参数转为[]reflect.Value并调用Call方法执行,返回值为[]reflect.Value类型,需注意参数类型和数量匹配,避免panic。 在Golang中,反射(reflection)通过 reflect 包实现,可以动态…

    2025年12月16日
    000
  • Golang如何处理channel关闭和读写异常

    关闭channel应由发送方执行,接收方关闭或重复关闭会导致panic;使用value, ok := 在Go语言中,channel是goroutine之间通信的核心机制。正确处理channel的关闭以及读写时可能出现的异常,对程序的稳定性至关重要。理解这些行为背后的规则,能避免常见错误,比如向已关闭…

    2025年12月16日
    000
  • Golang如何减少接口类型断言开销

    答案:减少Go语言类型断言开销的关键是避免重复断言和接口滥用。应缓存断言结果、优先使用具体类型代替interface{}、利用类型开关处理多类型场景,并减少数据的接口包装频率。通过将断言移出循环、使用具体参数类型或泛型替代interface{}、在类型开关中复用已转换值,以及避免基本类型的频繁装箱,…

    2025年12月16日
    000
  • 如何在Golang中配置Lint和格式化工具

    使用gofmt、revive和golangci-lint可统一代码风格并提升质量。首先gofmt自动格式化代码,建议在编辑器中启用保存时自动格式化,并通过gofmt -l .检查未格式化文件;其次revive替代已归档的golint,支持自定义规则(如空白导入、导出命名),通过.revive.tom…

    2025年12月16日
    000
  • Golang文件操作性能提升实践

    答案:通过缓冲、接口组合与并发优化Go文件操作性能。使用bufio减少系统调用,合理设置读写缓冲;利用io.Copy、io.Pipe等接口组合实现高效数据流转;结合Goroutine并行处理多文件或分片任务,提升吞吐;避免频繁开闭文件、滥用递归遍历,复用句柄并适时调用Sync持久化。 在Go语言开发…

    2025年12月16日
    000
  • Golang文件压缩解压功能实现项目

    Go语言通过archive/zip和compress/gzip包实现文件压缩解压,支持ZIP多文件打包与GZIP单文件压缩,结合合理项目结构可构建高效工具。 在Go语言开发中,处理文件的压缩与解压是常见的需求,比如日志归档、数据备份或文件传输优化。Golang标准库提供了强大的支持,尤其是 arch…

    2025年12月16日
    000
  • Golang文件写入如何保证数据安全

    使用临时文件+原子重命名可确保文件写入安全,先写入临时文件并调用Sync()落盘,再通过os.Rename()原子替换原文件,避免异常导致的数据损坏。 在使用Golang进行文件写入时,保证数据安全的核心在于确保写入过程的完整性、防止数据丢失或损坏。尤其是在程序崩溃、系统断电等异常情况下,仍能保障文…

    2025年12月16日
    000
  • Golang Bridge模块拆分与桥接模式示例

    桥接模式通过分离抽象与实现提升代码可维护性,Go中结合包机制将Device接口与Remote控制器解耦,实现TV和Radio等设备的独立扩展,新增设备无需修改控制逻辑,符合开闭原则。 在Go语言中,模块拆分和设计模式的合理运用能显著提升代码的可维护性和扩展性。桥接模式(Bridge Pattern)…

    2025年12月16日
    000
  • Golang fmt包格式化输出使用示例

    Go语言fmt包提供格式化输入输出功能,常用函数有Print、Println、Printf和Sprintf。通过格式动词如%v、%d、%s等控制输出形式,支持宽度、精度、对齐及类型信息打印,提升开发调试效率。 Go语言中的fmt包提供了丰富的格式化输入输出功能,适用于打印、调试和字符串拼接等场景。掌…

    2025年12月16日
    000
  • Golang反射实现通用拷贝函数示例

    使用reflect实现通用拷贝需确保源和目标类型一致且目标为可设置的指针;2. 通过Elem()获取指针指向的值;3. 遍历结构体字段或递归处理嵌套类型;4. 仅复制公共字段(首字母大写);5. 支持基础类型、切片、map及指针的深拷贝,但不处理循环引用。 在Go语言中,反射(reflect)可以用…

    2025年12月16日
    000

发表回复

登录后才能评论
关注微信