go | 写一个c/s 服务器 采用utf-8编码 | 抓包简单分析

原来 go 实现 c/s是这么方便的啊

server.go

go 复制代码
package main

import (
        "bufio"
        "bytes"
        "fmt"
        "golang.org/x/text/encoding/unicode"
        "golang.org/x/text/transform"
        "io"
        "net"
        "os"
        "strings"
        "time"
)

func main() {

        addr, err := net.ResolveUDPAddr("udp", ":8080")
        if err != nil {
                panic(err)
        }

        conn, err := net.ListenUDP("udp", addr)

        if err != nil {
                panic(err)
        }
        defer conn.Close()

        buf := make([]byte, 1024)

        utf8Decoder := unicode.UTF8.NewDecoder()
        for {
                n, addr, err := conn.ReadFromUDP(buf)
                if err != nil {
                        fmt.Println("read error: ", err)
                        continue
                }

                decodedReader := transform.NewReader(bufio.NewReader(bytes.NewReader(buf[:n])), utf8Decoder)
                decodedBytes, _ := io.ReadAll(decodedReader)

                fmt.Printf("Received from [%s] and the message is\n%s\n", addr, string(decodedBytes))

                reader := bufio.NewReader(os.Stdin)
                fmt.Println("Enter message: ")
                response, _ := reader.ReadString('\n')

                response = time.Now().Format(time.RFC3339) + " " + response

                utf8Encoder := unicode.UTF8.NewEncoder()

                // 使用 UTF-8 编码器编码要发送的数据
                encodedReader := transform.NewReader(strings.NewReader(response), utf8Encoder)
                encodedBytes, _ := io.ReadAll(encodedReader)

                conn.WriteToUDP(encodedBytes, addr)
        }
}

client.go

go 复制代码
package main

import (
        "bufio"
        "bytes"
        "fmt"
        "golang.org/x/text/encoding/unicode"
        "golang.org/x/text/transform"
        "io"
        "net"
        "os"
        "strings"
        "time"
)

func main() {

        addr, err := net.ResolveUDPAddr("udp", "localhost:8080")

        if err != nil {
                panic(err)

        }

        conn, err := net.DialUDP("udp", nil, addr)
        if err != nil {
                panic(err)
        }
        defer conn.Close()

        reader := bufio.NewReader(os.Stdin)
        buf := make([]byte, 1024)
        for {

                fmt.Println("Enter message: ")
                message, _ := reader.ReadString('\n')

                message = time.Now().Format(time.RFC3339) + " " + message

                utf8Encoder := unicode.UTF8.NewEncoder()
                encodedReader := transform.NewReader(strings.NewReader(message), utf8Encoder)
                encodedBytes, _ := io.ReadAll(encodedReader)

                conn.Write(encodedBytes)

                n, _, err := conn.ReadFromUDP(buf)

                if err != nil {
                        fmt.Println("read err: ", err)
                        continue
                }

                utf8Encoder_ := unicode.UTF8.NewDecoder()

                decodedReader := transform.NewReader(bufio.NewReader(bytes.NewReader(buf[:n])), utf8Encoder_)
                decodedBytes, _ := io.ReadAll(decodedReader)

                fmt.Printf("Received from [%s] and the message is\n%s\n", addr, string(decodedBytes))
        }

}

抓包分析

tcpdump -vvv -n -i any -s0 port 8080 -w test.pcap

分析这个包

分析这个高也是可是很好的学习网络结构的

你会发现 linux cooked capture 这就是链路层

ip 协议就是网络层 20B 主要就是src 和 dst ip

这层协议就是找ip

接着是udp 传输数据。

udp 协议头8B

当两端确定好了(也就是找到src 和 dst)

就可以开始传输数据,这就是面向服务了,直接通过端口面向服务

这里有一个知识点,5分唯一性? 就是 src + src:port + 协议 + dst + dst:port

然后又可以扯远 timeout 、端口复用

相关推荐
左手の明天6 小时前
SLIP 协议封装与解析详解:原理、C 代码与实战案例
linux·c语言·开发语言·c++
福大大架构师每日一题6 小时前
ollama v0.35.0发布:决策模型正式上线,接口直接返回选择、概率与评分
golang
一条破秋裤6 小时前
Linux 共享内存通信:POSIX 共享内存与 mmap
linux·运维·服务器
贵州山魈羡民7 小时前
【玩转手机】通过 Podroid 上的 Alpine 部署 1Panel,把微型服务器装进口袋
运维·服务器
小灰灰搞电子7 小时前
C语言 <ctype.h> 头文件详解
c语言·ctype.h
阿钱真强道8 小时前
17 嵌入式操作系统 | uloop 事件循环:TCP 客户端
c语言·tcp/ip·tcp·事件循环·uloop
程序员-Benothing9 小时前
Shell输入输出详解:read、echo、printf、颜色输出
linux·运维·服务器
茉莉玫瑰花茶9 小时前
GO [ 泛型 ]
golang
FPGA小徐9 小时前
从 NEMU 到 AbstractMachine:程序、运行时环境与 AM 完全解析
linux·运维·服务器
会员果汁10 小时前
函数调用和变长参数
c语言