返回列表 发布新帖
查看: 24|回复: 0

Go语言Socket:TCP 和 UDP 示例详解

发表于 2025-9-5 14:05:31 | 查看全部 |阅读模式

这里或许是互联网从业者的最后一片净土,随客社区期待您的加入!

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在网络编程中,Socket(套接字)是一个非常重要的概念。它是一个抽象的数据结构,用于表示网络中的一个端点,包含了 IP 地址、端口号以及协议类型等信息。Go 语言提供了强大的 net 包,使得 Socket 编程变得更加简便。本文将详细介绍 Go 语言如何实现 TCP 和 UDP Socket 编程。
1. Socket 编程基本原理
Socket 编程基于客户端-服务器模型,其中:
  • 客户端:发起请求的一方。
  • 服务器:提供服务的一方。

通过 Socket,客户端可以向服务器发送请求,服务器接收到请求后进行处理并返回响应。
常见的协议类型
  • TCP(传输控制协议):面向连接的协议,可靠、保证数据有序传输,适用于对数据传输有严格要求的场景。
  • UDP(用户数据报协议):无连接的协议,不保证数据可靠传输,适用于对实时性要求较高的场景。

Go 语言通过 net 包提供了对这两种协议的支持,使得开发者能够轻松实现网络通信。
2. TCP Socket 编程2.1 服务器端实现
TCP 是一种面向连接的协议,适合需要可靠数据传输的场景。以下是一个简单的 TCP 服务器实现,它会监听指定端口并回显接收到的消息。
  1. package main

  2. import (
  3.     "bufio"
  4.     "fmt"
  5.     "net"
  6. )

  7. func handleConnection(conn net.Conn) {
  8.     defer conn.Close()
  9.     reader := bufio.NewReader(conn)
  10.     for {
  11.         // 读取客户端发送的数据
  12.         message, err := reader.ReadString('\n')
  13.         if err != nil {
  14.             fmt.Println("读取数据错误:", err)
  15.             break
  16.         }
  17.         fmt.Printf("收到消息: %s", message)
  18.         // 回显消息给客户端
  19.         conn.Write([]byte("Echo: " + message))
  20.     }
  21. }

  22. func main() {
  23.     // 监听本地 8080 端口
  24.     listener, err := net.Listen("tcp", ":8080")
  25.     if err != nil {
  26.         fmt.Println("监听端口失败:", err)
  27.         return
  28.     }
  29.     defer listener.Close()
  30.     fmt.Println("服务器正在监听端口 8080...")

  31.     for {
  32.         // 接受客户端连接
  33.         conn, err := listener.Accept()
  34.         if err != nil {
  35.             fmt.Println("接受连接失败:", err)
  36.             continue
  37.         }
  38.         // 为每个连接启动一个新的 goroutine 进行处理
  39.         go handleConnection(conn)
  40.     }
  41. }
复制代码
说明
  • 使用 net.Listen 监听指定的 IP 地址和端口。
  • 通过 listener.Accept 接受客户端的连接,返回一个 net.Conn 对象。
  • 每当接收到一个连接时,通过 goroutine 并发处理该连接。

2.2 客户端实现
以下是一个简单的 TCP 客户端示例,连接到服务器并发送消息。
  1. package main

  2. import (
  3.     "bufio"
  4.     "fmt"
  5.     "net"
  6.     "os"
  7. )

  8. func main() {
  9.     // 连接到服务器(localhost:8080)
  10.     conn, err := net.Dial("tcp", "localhost:8080")
  11.     if err != nil {
  12.         fmt.Println("连接服务器失败:", err)
  13.         return
  14.     }
  15.     defer conn.Close()

  16.     reader := bufio.NewReader(os.Stdin)
  17.     for {
  18.         // 从标准输入读取用户输入
  19.         fmt.Print("请输入消息: ")
  20.         message, _ := reader.ReadString('\n')
  21.         // 发送消息到服务器
  22.         _, err := conn.Write([]byte(message))
  23.         if err != nil {
  24.             fmt.Println("发送消息失败:", err)
  25.             return
  26.         }
  27.         // 接收服务器回显的消息
  28.         response, err := bufio.NewReader(conn).ReadString('\n')
  29.         if err != nil {
  30.             fmt.Println("接收消息失败:", err)
  31.             return
  32.         }
  33.         fmt.Print("服务器回显: " + response)
  34.     }
  35. }
复制代码
说明
  • 使用 net.Dial 连接到服务器。
  • 从标准输入读取用户输入并将其发送到服务器。
  • 接收服务器回显的消息并显示。

3. UDP Socket 编程
UDP 是一种无连接的协议,适合对实时性要求较高但对数据传输可靠性要求不高的场景。下面是如何在 Go 中实现 UDP 服务器和客户端。
3.1 服务器端实现
以下是一个简单的 UDP 服务器实现,它监听指定端口,接收客户端发送的数据,并回显消息。
  1. package main

  2. import (
  3.     "fmt"
  4.     "net"
  5. )

  6. func main() {
  7.     // 监听本地 8081 端口的 UDP
  8.     addr, err := net.ResolveUDPAddr("udp", ":8081")
  9.     if err != nil {
  10.         fmt.Println("解析地址失败:", err)
  11.         return
  12.     }

  13.     conn, err := net.ListenUDP("udp", addr)
  14.     if err != nil {
  15.         fmt.Println("监听 UDP 失败:", err)
  16.         return
  17.     }
  18.     defer conn.Close()
  19.     fmt.Println("UDP 服务器正在监听端口 8081...")

  20.     buffer := make([]byte, 1024)
  21.     for {
  22.         // 读取客户端发送的数据
  23.         n, clientAddr, err := conn.ReadFromUDP(buffer)
  24.         if err != nil {
  25.             fmt.Println("读取数据错误:", err)
  26.             continue
  27.         }
  28.         message := string(buffer[:n])
  29.         fmt.Printf("收到来自 %s 的消息: %s", clientAddr, message)

  30.         // 回显消息给客户端
  31.         _, err = conn.WriteToUDP([]byte("Echo: "+message), clientAddr)
  32.         if err != nil {
  33.             fmt.Println("发送消息失败:", err)
  34.         }
  35.     }
  36. }
复制代码
说明
  • 使用 net.ResolveUDPAddr 解析 UDP 地址。
  • 使用 net.ListenUDP 监听指定的端口。
  • conn.ReadFromUDP 用于接收客户端数据,并返回客户端地址。

3.2 客户端实现
以下是一个简单的 UDP 客户端实现,发送消息到服务器并接收回显。
  1. package main

  2. import (
  3.     "bufio"
  4.     "fmt"
  5.     "net"
  6.     "os"
  7. )

  8. func main() {
  9.     // 解析服务器地址
  10.     serverAddr, err := net.ResolveUDPAddr("udp", "localhost:8081")
  11.     if err != nil {
  12.         fmt.Println("解析服务器地址失败:", err)
  13.         return
  14.     }

  15.     // 创建一个 UDP 连接(实际上是无连接的)
  16.     conn, err := net.DialUDP("udp", nil, serverAddr)
  17.     if err != nil {
  18.         fmt.Println("连接 UDP 服务器失败:", err)
  19.         return
  20.     }
  21.     defer conn.Close()

  22.     reader := bufio.NewReader(os.Stdin)
  23.     for {
  24.         // 从标准输入读取用户输入
  25.         fmt.Print("请输入消息: ")
  26.         message, _ := reader.ReadString('\n')
  27.         // 发送消息到服务器
  28.         _, err := conn.Write([]byte(message))
  29.         if err != nil {
  30.             fmt.Println("发送消息失败:", err)
  31.             return
  32.         }
  33.         // 接收服务器回显的消息
  34.         buffer := make([]byte, 1024)
  35.         n, err := conn.Read(buffer)
  36.         if err != nil {
  37.             fmt.Println("接收消息失败:", err)
  38.             return
  39.         }
  40.         fmt.Print("服务器回显: " + string(buffer[:n]))
  41.     }
  42. }
复制代码
说明
  • 使用 net.ResolveUDPAddr 解析服务器地址。
  • 使用 net.DialUDP 创建一个 UDP 连接(实际上是无连接的)。
  • 客户端向服务器发送消息并接收回显。

4. 总结
Go 语言通过其强大的 net 包,简化了 Socket 编程,支持常见的 TCP 和 UDP 协议。无论是需要可靠数据传输的 TCP,还是对实时性要求高的 UDP,Go 都能轻松实现。通过学习本文中的示例,你可以掌握基本的 Socket 编程技巧,并能够在实际应用中灵活运用这些技术。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2001-2025 Suike Tech All Rights Reserved. 随客交流社区 (备案号:津ICP备19010126号) |Processed in 0.130052 second(s), 8 queries , Gzip On, MemCached On.
关灯 在本版发帖返回顶部
快速回复 返回顶部 返回列表