https://blog.csdn.net/huaishu/article/details/93739446
1 报文格式
网络上传输的报文由以下部分组成
以太网头14字节
Ip头20字节
Tcp头20字节
数据
1.1 例子
以太网数据帧:
1.1.1 以太网头
从截图看是14字节,定义了源和目的的MAC地址
1.1.2 IP头
20字节,定义了源ip目的ip等信息。
1.1.3 tcp头
20字节,定义了源端口,目的端口等信息
1.1.4 数据
数据部分,截图中,左边是字节流,右边是对应的ASCII码。可以看出我们真正要发送的数据是:HTTP/1.1 200..是一个响应报文。
2 tcp报文格式
其中上面的tcp头+数据组成tcp报文。
从上图tcp报文格式我们可以知道,为什么端口号最大65535个,2^16=65536
3 以太网上的传输
在以太网上,我们采用分组交换技术进行数据传输,首先,我们会对要传输的数据进行分组,每一个分组+以太网头+IP头+tcp头组成帧,在数据链路层上进行传播。数据链路层协议会把帧转化为高低电平在物理层(共享介质)上进行广播。同一局域网中广播。
4 Seq和Ask的计算
Seq和Ask是tcp层的概念,是tcp头中定义的,用于标识数据从什么位置开始发送,数据已经接收到什么位置了。
首先,我们要明白一个道理,对于数据通信的双方,他们的地位是相等的,没有客户端和服务端的区别,在一个时刻,甲是发送方乙是接收方,而在另一个时刻,可能乙是发送方甲是接收方。
4.1 三次握手
第一次握手
甲向乙发请求,甲的Seq随机生成一个随机数,甲的Ask=0;乙的Seq和Ask此刻都还没初始化
甲向乙发送Seq=4000590757,Ack=0,告诉乙我想和你通信,我将从这个位置4000590757开始传送数据,我也已准备好接收。
第二次握手
乙向甲发请求,乙的Seq随机生成,乙的Ask是甲的Seq+1
乙接收到报文,设置Ask=甲Seq+1=4000590758,Seq随机生成3573713383。乙向甲发报文Seq和Ask,告诉甲,我收到你的报文,我也准备好接收,从4000590758开始接收,我也准备好发送,从3573713383开始发送
第三次握手
甲向乙发请求,甲的Seq在上次请求的基础上+1,甲的Ask是乙的Seq+1
4.2 三次握手说明
经过3次握手,
甲明确了,发送数据,我将从4000590758开始发送,我将在3573713384开始接收
乙明确了,发送数据,我将从3573713384开始发送,我将在4000590758开始接收
从这个角度我们可以解释为什么需要3次握手。
4.3 传输数据
下面以相对Seq和Ask说明
4.3.1
4.3.2
甲Seq:1+120=121
4.3.3
对4.3.1的应答报文,Seq不变表示没有要发的数据。Ask应答,表示对4.3.1的应答,Ask=初始值+接收报文长度=1+120=121
4.3.4
对4.3.2的应答报文,Seq不变表示没有要发的数据。Ask应答,表示对4.3.1的应答,Ask=初始值+接收报文长度=121+24=145
同时,甲收到应答报文后,Seq更新,新Seq=老Seq+发送的报文长度=121+24=145
4.3.1和4.3.2是请求报文,请求内容为,4.3.1发送请求头和请求行,4.3.2发送请求体
POST http://192.168.xxx.xx:8080/api/produce/globalInfo HTTP/1.1
Content-Type: application/json
{"uid":"xxx"}
4.3.3和4.3.4分别为4.3.1和4.3.2的响应报文,报文载荷长度为0,作用是告诉甲收到请求了。
4.3.5
乙向甲发送报文,从位置Seq=1发送1460字节
4.3.6
继续发送另一个tcp报文,从Seq=1461位置开始发送
4.3.7
甲收到报文,向乙发送确认收到报文,Seq=145不变,Ack=1+1460+1073=2534表示已经接收到这个位置了。
4.3.8
乙给甲发送,Seq=1461+1073=2534,表示已经发到这个位置了。Ack=145不变.另外有5字节的数据量,猜测是传输完毕的标志,通信完毕,接下来要发送四次挥手。