PHP程序员如何理解TCP协议

发布于 2022-09-12 04:30:23 字数 256 浏览 24 评论 0

做PHP非常久,然后打算转Go,写过几个go的服务,但都是原生的代码自己写的。最近转Go,修改别人的一个Go框架,里面是微服务之间使用TCP协议进行相互握手,秘钥交换,这一块一直都感觉特别晕,之前是只做网站,HTTP请求来一个处理一个再返回断开,但TCP的建立连接之后相互发送数据。

想提问,这样的水平情况,如何能快速理解这种TCP的协议交换。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

但可醉心 2022-09-19 04:30:23

理解成一个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)
    }

写数据也是一样的道理:

  1. 先计算需要写的长度,转换成byte数组发送,然后再发送body。
    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就应该增加长度

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文