你需要知道的TCP/IP( 三 )


5、到下一个路由器节点,路由器解包,看是发给自己的数据包(根据帧中的目的 MAC 地址与自己的 MAC 地址比较),不是就丢弃了;是的话就会解包拿到 目的 IP (47.104.168.20),然后在当前路由器上根据路由表查询下一跳,发送给下一个节点; 。。。。直到目的服务器,或者发送的包 TTL 为 0
6、发到目的服务器的网卡上,网卡将数据复制到内核缓冲区,应用程序从缓冲区中读取数据
IP 数据格式IPv4 数据结构

你需要知道的TCP/IP

文章插图
 
图来自《图解 TCP/IP》
  • 版本(Version):4 bit 构成,代表当前 IP包是哪个版本,IPv4 或者 IPv6,为 4 时表示当前是 IPv4 。
  • 首部长度(Internet Header Length):由 4 bit 构成,一般 20字节大小 。
  • 标识(Identification):用于分片重组用,值相同的属于同一个 IP 数据包
  • 标志(Flags):用于判断是否还有分片 。
  • 总长度(Total Length):16 个字节,IP 数据包总的长度,最长可为 65525 字节 。
  • 分段偏移(Fragment Offset):表示这个包在原来 IP 包中的位置 。
  • 生存时间 TTL(Time To Live): IP 包在路由转发中存活的时间,被路由转发一次,次数减 1,为 0 时,数据包被丢弃 。
  • 挂载协议标识 (Protocol):记录数据包中 Data(实际发送的数据)是什么类型的数据,1 标识 ICMP, 4 标识 IP, 6标识 TCP, 17 标识 UDP 。根据这个挂载协议程序就知道调用哪些接口来进行后续的处理了 。
数据链路层中以太网数据帧的 MTU 是 1500 字节,限定了 IP 数据包最大为 1500 字节 。然后去掉 IP 包首部 20 字节,一般 IP 数据包发送的数据为 1480 字节 。
当我们发送一个 3058 字节的 IP 数据包时,这显然大于了数据链路层的 MTU (1500 字节) 。所以网络层会对大于链路层MTU 的数据包进行分片 。拆分一个一个的1500 的数据包发送接收端,接收端接收到这三个包,在汇聚成一个完成的,在调用传输层接口 。
# 会发送 3050 字节数据与 8 字节的 ICMP 首部,这个命令会总共发送 ip 数据大小 3058 字节 。ping -s 3050 www.mflyyou.cn
你需要知道的TCP/IP

文章插图
 

你需要知道的TCP/IP

文章插图
 

你需要知道的TCP/IP

文章插图
 

你需要知道的TCP/IP

文章插图
 
通过 wireshark 抓包可以看到,IP 数据包的首部长度占了 20 字节,实际每次发送数据为 1480 字节,最后一次发送了 98 字节 。
从 Fragment 和 Identification 可以看到这三个包属于同一个 IP 数据包,并且从 Fragment offset 能将这三个包合成一个完成的网络层数据包 。
传输层 TCPTCP 是面向链接的,可靠的,全双工协议 。
面向连接就是发送之前,需要建立一个链接通道,数据都是在这个链接中发送 。
TCP 协议中发送端会记录发送的那些数据包被客户端收到了 。接收端接受数据之后,会回复一个 ACK 包(由数据格式中的控制位决定),确认应答号告诉发送端哪些数据包接收到了 。
发送端发送了数据包之后,这个包会有一个重发倒计时,在这个倒计时内没有收到接收端回复 ACK 包,就会再重发一个数据包 。如果是 HTTP 请求,就相当于同样的数据请求了两次 。
我们知道支付接口都要求幂等性,有一部分原因是因为这个超时重发 。发送端发送了请求,接收端处理好业务之后回复的 ACK 包超时,发送端超时重发这个请求 。如果不保证接口的幂等性,那么扣钱就会扣两次 。
我们要做的就是保证这个重发 n+1 次不再扣用户的钱,一般会用一个 token 来判断是不是重复请求,重复就不走扣款处理了,直接返回已经支付,保证接口的幂等性 。或者用一个账单流水来保证幂等性 。
连接既然需要建立,那么也会有连接断开 。断开连接需双方协商好之后断开连接,不能单方面关闭而不管对方 。因为建立连接之后占用的计算机资源需要释放掉 。你单方面强制断开连接释放了资源,但是对方不知道需要断开连接,分配的计算机资源一直占用那就是不可靠协议了 。所以 TCP 有四次挥手断开连接 。
全双工就是连接两边都可以主动发送接受数据,而不是轮训访问有没有数据到达 。
TCP 数据格式首先我们要先了解 TCP 数据格式,才能更容易知道 TCP 的工作原理 。


推荐阅读