做PHP非常久,然后打算转Go,写过几个go的服务,但都是原生的代码自己写的。最近转Go,修改别人的一个Go框架,里面是微服务之间使用TCP协议进行相互握手,秘钥交换,这一块一直都感觉特别晕,之前是只做网站,HTTP请求来一个处理一个再返回断开,但TCP的建立连接之后相互发送数据。
想提问,这样的水平情况,如何能快速理解这种TCP的协议交换。
理解成一个TCP连接就是两根相反流动的水管,水就是其中的数据,数据是没有边界的,水流也没有界限,因此你需要根据水流的大小,来截取对应的数据,解码成你需要的数据。
比如协议规定tcp 的头部2个字节表示长度,余下的字节表示body部分的具体内容(具体协议可以自定义)
于是我在第一次读取数据的时候,先读取2个字节,然后把这两个字节转成10进制,就是body的长度. 然后重新生成body的数组,继续读:
var conn net.Conn type YourStruct struct { Username string `json:"username"` } for { b := make([]byte, 2) _, err := io.ReadFull(conn, b) if err != nil { return } length := binary.BigEndian.Uint16(b) body := make([]byte, length) _, err = io.ReadFull(conn, body) if err != nil { return } // 解析结构体 var v = new(YourStruct) json.Unmarshal(body, v) fmt.Println(v.Username) }
写数据也是一样的道理:
var conn net.Conn type YourStruct struct { Username string `json:"username"` } for { v := YourStruct{Username: "hahah"} data, _ := json.Marshal(v) header := make([]byte, 2) binary.BigEndian.PutUint16(header, uint16(len(data))) // 写头 conn.Write(header) // 写body conn.Write(data) }
tcp的边界定义就是跟据你定的协议,组装好数据包,发送的时候组装包,获取的时候拆包.2个字节的头,body最长应该是65535个字节,超过这个长度,header就应该增加长度
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
暂无简介
文章 0 评论 0
接受
发布评论
评论(1)
理解成一个TCP连接就是两根相反流动的水管,水就是其中的数据,
数据是没有边界的,水流也没有界限,因此你需要根据水流的大小,来截取对应的数据,解码成你需要的数据。
比如协议规定tcp 的头部2个字节表示长度,余下的字节表示body部分的具体内容(具体协议可以自定义)
于是我在第一次读取数据的时候,先读取2个字节,然后把这两个字节转成10进制,就是body的长度. 然后重新生成body的数组,继续读:
写数据也是一样的道理:
tcp的边界定义就是跟据你定的协议,组装好数据包,发送的时候组装包,获取的时候拆包.
2个字节的头,body最长应该是65535个字节,超过这个长度,header就应该增加长度