Socket为什么需要创建一个缓冲区

47 min read

在Go语言中,你可以使用net包来实现socket编程¹²。你可以创建一个socket服务器,监听一个端口,等待客户端的连接请求。你也可以创建一个socket客户端,向服务器发送连接请求,然后与服务器进行数据交换。

以下是一个简单的例子,展示了如何用Go语言编写一个socket服务器和一个socket客户端³:

Socket服务器

package main

import (
	"fmt"
	"net"
)

func main() {
	// 1. 通过创建一个监听器listener,监听TCP协议的8080端口
	listener, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer listener.Close()

	fmt.Println("Server is listening...")

	for {
		// 2. 通过监听器listener接受客户端的连接请求
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println(err)
			return
		}

		go handleConnection(conn) // 3. 每来一个请求,就会启动一个goroutine来处理
	}
}

func handleConnection(conn net.Conn) {
	defer conn.Close()

	for {
		buf := make([]byte, 1024) // 4.创建一个缓冲区

		n, err := conn.Read(buf) // 5.从连接中读取数据,返回实际读取的二进制数据长度
		if err != nil {
			fmt.Println(err)
			return
		}

        fmt.Printf("Received %d bytes: %s\n", n, string(buf[:n])) // 打印接收到的数据

        _, err = conn.Write(buf[:n]) // 6.将接收到的数据回写给客户端
        if err != nil {
            fmt.Println(err)
            return
        }
    }
}

Socket客户端

package main

import (
    "fmt"
    "net"
)

func main() {
    // 连接到本地的8080端口
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer conn.Close()

    for {
        var input string

        fmt.Scanln(&input) // 从标准输入读取一行数据

        _, err = conn.Write([]byte(input)) // 将输入的数据发送给服务器
        if err != nil {
            fmt.Println(err)
            return
        }

        buf := make([]byte, 1024) // 创建一个缓冲区

        n, err := conn.Read(buf) // 从连接中读取数据
        if err != nil {
            fmt.Println(err)
            return
        }

        fmt.Printf("Received %d bytes: %s\n", n, string(buf[:n])) // 打印接收到的数据
        
    }
}

Intro to Socket Programming in Go | Developer.com. https://www.developer.com/languages/intro-socket-programming-go/ 访问时间 2023/2/25.
(2) Socket Server | Learn Go Programming. https://golangr.com/socket-server/ 访问时间 2023/2/25.
(3) Getting Started with Sockets Concurrently in GoLang. https://dev.to/alicewilliamstech/getting-started-with-sockets-in-golang-2j66 访问时间 2023/2/25.

创建一个缓冲区的目的是为了在网络通信中提高数据传输的效率和安全性。缓冲区是一块内存空间,用于暂时存储发送或接收的数据。有了缓冲区,你可以一次性读写大量的数据,而不是逐个字节地处理,这样可以减少系统调用和网络延迟。同时,缓冲区也可以保护数据源或目标,防止因为网络故障或攻击而造成数据丢失或损坏¹²。