好久没有写在前面了,这次写下。很久没有更新,csdn 估计要忘了我了,排名一直在掉,提笔写这篇文章,说实话,从题目定了,到下笔,中间大概有 3 天之久,到完成可能还更晚。一来是最近可能有点忙,二来有点不知道该如何提笔了,有时候在想 ”意义“ 二字。有时会颓然觉得,所思所想所做,都无甚大意义,大抵如此。
说回技术文章,我看技术文章有个毛病,看长篇大论,很容易就不想看了,密密麻麻写了一堆,我靠,我根本不想看好嘛。
然鹅,到我写的时候,也不可避免的会堆一些学术文档来说明。确实很恶心,但又有啥办法呢,为了能够明确主题和主旨,所以加个模块 《本文将带你学会》总结一下我这篇文章将为你带来什么,你能从这里 get 到什么。避免大家浪费时间是不。
文章我尽量写的简洁一点,把我在学习过程中疑惑的点整理出来。
害,干货啊干货,前有干货,所以,三连很有用。
1. 从 wireshark 中来看面试中常问的 tcp 三次握手 四次挥手 真正的数据面目到底是什么?
2. 看到 TCP/IP 五层模型的具象化真实表达
3. 网络传输中 TCP 头全解析
上图,三次握手 建立连接,请求接口传输数据。这个时候请求结束,TCP 进行了一波 Keep-Alive
最后服务端向我请求端发起了断链,进行了四次挥手 断开连接。
三次握手建立连接,四次挥手断开连接。这个我们在后面讲为什么要这么做。重点看数据包中都发了写什么
首先拿第一个 SYN 请求连接包来举例看
这里可以具象化地看到,我们所谓的分层都是些什么东西,他们的实际表现形式
物理层: Frame 11561: 78 bytes on wire (624 bits), 78 bytes captured (624 bits) on interface en0, id 0
数据链路层: Ethernet II, Src: Apple_cb:e5 (90::cb:ec:c5), Dst: Huaa:04 (ac:7:40:ea:04)
网络层: Internet Protocol Version 4, Src: 172.16.25.144, Dst: 192.168.26.144
传输层: Transmission Control Protocol, Src Port: 58173, Dst Port: 18080, Seq: 0, Len: 0
应用层: 这里没有,下面 HTTP 协议就有了
应用层: Hypertext Transfer Protocol
看到这里有些蒙的同学可以看看我之前的文章,补补课复习一下
网络编程之 Socket 编程 一文看懂
网络分层流转—从浏览器请求到服务端响应究竟经历了什么?
本篇重点是 传输层协议 TCP ,篇幅问题,就不节外生枝,直接走主线
在这里我要放一下,网络上都放烂了的图,当然我会抄一遍,用自己的形式展示出来 [狗头]
给了图,不解释下什么意思,就是耍流氓了,这里大概给个解释,让大家对这个设计有个理解
源端口号 Source Port: 一般来说就是客户端发起请求时使用的端口号,这个在浏览其发起请求时会自动分配一个。比如这里我被分配的端口号就是 58173。这个作用是服务端给你返回数据的时候能找到你客户端的端口
目的端口号 Destintion Port: 这个就是你要访问的服务的端口号,比较常用的如 8080 ,我这里是 18080。同理,你请求到了服务端总要知道服务是由哪个端口提供的吧。
序号 Sequence Number: TCP 为了保证包的顺序到达,就需要给每个包一个需要来标识它的顺序,它解决了乱序的问题,当然这个逻辑也是在两端程序逻辑控制的,真正的包到了网络中是怎么样的,那对你来说可就是鞭长莫及干瞪眼了。(祈祷他能平安到达吧)
关于序号的生成规则
TCP 是面向字节流的,这意味着 TCP 在传输数据的过程中会为每个字节按照顺序进行编号。例如对于传输 10 kb 的 HTML 文档
10 kb = 10 * 1024 byte = 10240 byte 一共 10240 个字节。
序号是 32 位 是 2^32 是 4 294 967 296 = 4G 所以 TCP 可以对 4G 的数据进行编号,超过之后回 0 重新计数
那对于上面的 10 kb 其编号范围就是 [0,10239]
这里的序号标识的是此报文段中,数据的第一个字节的序号,如上述 10 kb 数据我们分成两等分传输
第一段: 5 kb Sequence Number = 0 ; 其范围是 [0,5119]
第二段: 5 kb Sequence Number = 5120 ; 其范围是 [5120,10239]
相信大家可能注意到了一点,超出 4G 重复使用编号的问题,这种情况其实基本不用担心,一般情况,旧的序号早就到达终点,或者丢失了。
确认序号 Acknowledgement Number: 为了保证可靠性,发出去的包需要确认到达,就有了确认序号,这个解决了丢包的问题,一定时间没确认收到就重发嘛。我们 TCP 能做啥呢,就是不断的重传,寄希望于能得到对端的收到确认,卑微也就至此了。
同样的 32 位确认序号,表示的是 期望收到对方下一个报文的序号值。
TCP 的可靠就是基于此,我们要确认每个发送出的报文都被确认收到了。
通讯双方在接到对方的报文后,都需要发送一个对应的确认报文,要告知已经收到,有确认报文就需要确认好
如第一段: 5 kb Sequence Number = 0 ; 其范围是 [0,5119] 发送过来,此时回 ACK 确认报文 Acknowledgement Number = 5120
标志位 Flags: 标志位共 16 位,首部占 4 位,保留 6 位,剩余 6 位每没一位标志不同的意思
窗口大小 Window : 16 位,该字段指定此时允许对方发送的最大数据量,也就是说此数据是我方缓冲区剩余大小,用于控制发送数据的速度
窗口大小是指,从本端报文的 确认序号 Acknowledgment Number 开始,还允许对方发送的数据量。
比如 Acknowledgment Number = 100 Window = 60 ,那么标识报文发送方还有 60 字节的接收空间,即序号范围是 [100,159] 的数据。
校验和 CheckSum: 16 位 用于检测 TCP 报文段在传输过程中有没有损坏,如果损耗则丢弃,采用 CRC 算法,这个是保证 TCP 可靠传输的重要一环。 具体生成校验规则,感兴趣同学可以自行搜索算法。
紧急指针 Urgent Pointer: 16 位 ,当标志位 URG 为 1 时有意义,用于指出报文段中紧急数据的字节数。发送方会将紧急数据插入到本次报文段的最前面,而后面的仍然是普通数据,紧急指针指示的是紧急数据的末尾在本段报文数据的位置。
给你们看看 16 进制表示,而老说的位 ”01010101“ 而进制传输本质是 01 嘛,为啥不给你看 01 ? 因为不好看哈哈
不想写了,本文到这,下期再见