json.Marshal
func Marshal(v any) ([]byte, error)
json.Marshal序列化为合法的json描述
type DictRequest struct {
TransType string `json:"trans_type"`
Source string `json:"source"`
UserID string `json:"user_id"`
}
request := DictRequest{TransType: "en2zh", Source: word}
buf, err := json.Marshal(request)
println(string(buf))
//{"trans_type":"en2zh","source":"hello","user_id":""}
var data = bytes.NewReader(buf)
json.Unmarshal
func Unmarshal(data []byte, v any) error
反序列化,从[]byte中解析到any中。
var dictResponse DictResponse,err = json.Unmarshal(bodyText, &dictResponse)
Socks5代理
工作原理
分为四个阶段:握手阶段、认证阶段、请求阶段、relay阶段
握手阶段
客户端先和代理服务器进行TCP三次握手建立连接
认证阶段
浏览器向代理服务器发一个包
+-----+----------+----------+
| VER | NMETHODS | METHODS |
+-----+----------+----------+
| 1 | 1 | 1 to 255 |
+-----+----------+----------+
VER: 协议版本号 socks5为0x05
NMETHODS: 客户端支持的认证方法数量
METHODS: 每个byte对应一个认证方法 0代表不需要认证, 2代表用户名密码认证
代理服务器返回一个应答数据包
+-----+--------+
| VER | METHOD |
+-----+--------+
| 1 | 1 |
+-----+--------+
METHOD: 指定认证方法。该方法应从客户端提供的认证方法中挑选一个,或者是X'FF'用以拒绝认证
请求阶段
客户端发送数据包来请求服务端
+-----+-----+-------+------+----------+----------+
| VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+-----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+-----+-----+-------+------+----------+----------+
VER 版本号,socks5的值为0x05 CMD 0x01表示CONNECT请求 RSV 保留字段,值为0x00 ATYP 目标地址类型,DST.ADDR的数据对应这个字段的类型。 0x01表示IPv4地址,DST.ADDR为4个字节 0x03表示域名,DST.ADDR是一个可变长度的域名 DST.ADDR 一个可变长度的值 DST.PORT 目标端口,固定2个字节
服务端返回对应的报文信息
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
VER socks版本,这里为0x05 REP Relay field,内容取值如下 X’00’ succeeded RSV 保留字段 ATYPE 地址类型 BND.ADDR 服务绑定的地址 BND.PORT 服务绑定的端口DST.PORT
delay阶段
建立客户端与下游服务器的双向数据转发