原来 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 、端口复用