03. TCP/IP 四层模型

OSI的7层过于复杂,于是有人简化了一下,改成了2层,软件部分是应用层,硬件部分是物理层。再后来,有人提出过于简单,又添加了两个新成员:TCP/IP在软硬件层之间。

各厂商遵循同一套协议,实现不同厂商之间的互联。协议就是一组规范,大家都能够明白的事实。

TCP/IP协议簇

03. TCP/IP 四层模型

传输层协议:TCP看做是买了保险,有保障;UDP看做是没有买保险,没有保障。TCP面向连接,所有能够可靠传输;UDP面向无连接,所以无法保证可靠性。

如何保证面向连接?—— 会话双方需要存在互动过程

  • TCP协议建立连接时需要完成三次捂手
  • TCP协议断开连接时需要完成四次挥手

协议簇的作用

最底层的以太网协议规定了电子信号如何转换成数据包,用来实现子网内部的点到点通信。但是,以太网协议不能实现子网间通信(局域网与局域网之间),所以依赖IP协议。

IP协议制定了一套自己的地址规则,俗称IP地址。用它实现三层路由功能,允许一个子网内的主机可以向另一个子网的主机发送消息。

如何实现三层路由功能的呢?

在路由器(三层转发的设备)里有n个接口,并且会有张路由表,专门记录路由条目。规定网段A走接口1,网段B走接口2……,实现数据包的转发。

IP协议只能用来指路,不能保证数据包是否抵达目的端。若是数据包在转发途中丢失,就需要知道是哪一个数据包没有正确传输(产生丢包)。 感知到丢包后,需要将没有抵达目的端的数据包进行重新发送。

如何确保0丢包?

就需要依赖TCP协议的可靠性。TCP保证数据通信的完整性,防止丢包。

TCP数据包

大小

以太网数据包的大小从1518字节扩展到1522字节(默认固定值)。其中,1500字节是负载(传输层一次能处理的最大能力);22字节是帧头信息。

IP数据包在以太网数据包的负载里面,IP头部占20字节,所以IP数据包的可用负载最多是1480字节

TCP数据包在IP数据包的负载里面,TCP头部最少也需要20字节,所以TCP数据包最大负载只有1460字节。实际情况,IP和TCP会有额外的头部信息,所以TCP负载的大小在1400字节左右。

综上,应用层产出一条1500字节的信息就需要2个TCP数据包。
03. TCP/IP 四层模型

编号 SEQ

一次产生大量数据,就需要分成多个包。比如,一个20M的文件,需要发送14200多个包。

往网络层发送数据包的时候,TCP协议为每个包进行编号,为了接收方能够还原出原始数据。在产生丢包时,也能知道是丢的那些包。

第一个包的编号是一个随机数,第二个包的编号是随机数+负载长度。例,第一个包的编号是1,负载大小是100字节,第二个包的编号就是1+100=101。

每个数据包都可以知道两个编号,自己本身的SEQ和下一个包的SEQ。接收方依据SEQ可以还原原始数据。

数据包组装过程

收到TCP数据包后,组装还原是通过操作系统完成的。应用程序不直接处理TCP数据包,而是处理TCP数据包里的数据。

TCP没有方式表示原始文件的大小。是需要通过应用层的协议来规定,例如HTTP协议的一个头信息Content-Length表示原始数据的大小。

操作系统做的是:不断的接收TCP数据包,并按照SEQ的编号组装好。并不处理TCP数据包里的数据。数据一旦被组装好后,就把他们转交给应用程序。

如何提交到正确的应用程序呢?

TCP数据包里会有一个port参数,操作系统根据port参数指定转交给监听此端口的应用程序。

例如,HTTP协议。浏览器接收到原始数据后,根据HTTP协议里Content-Length字段正确读取一段段完整的数据。也就是,一次TCP通信可以包含多个HTTP请求

慢启动与ACK

服务器端发送数据,当然是越快越好,要是一次就能发送出去,那就在好不过了。但是发的越快,丢包了怎么办。在带宽小、路由器性能差的线路上丢包概率会大大发生。

合理状态下,是在线路允许的最高速率下传输。那要怎么知道对方支持的最大速率是多少呢?被人告诉你?不可能的,只有通过慢慢试,找到一个平衡点。

TCP协议开始发送数据的时候,是慢慢发数据,通过丢包的情况,调整速率。若不丢包,就慢慢提高速度;若丢包,就降低发送速度。

在LINUX内核里有个常量是TCP_INIT_CWND,在通信开始,发送方一次性发送10个TCP数据包,也就是发送窗口为10。然后停止,等待接收方的确认,再继续发送。

默认,接收方收到两个TCP数据包,就要发送一个确认消息(ACK),表示自己收到了发送方的2个TCP数据包。ACK里有两个信息,一个是期待下一个数据包的编号,一个是接收方的接收窗口的剩余容量。发送方通过ACK消息,就能大致推测出接收方大概的接收速度,从而决定是降低发送速率,还是提高发送速率。这被称为“发送窗口“,窗口大小可变(可滑动)。

因为TCP通信是可靠双向的,所以双方都需要发送ACK。两方的窗口可能不同。ACK只有简单的几个字段,通常会和数据合并在一起发送。

数据包丢失处理

TCP协议怎么保证数据通信的完整性?

每个数据包都有一个下一个数据包的编号。如果下一个数据包编号没有收到,那ACK的编号就不再发生变化。

例,接收方收到4号包,没收到5号包。ACK就会记录,期待收到5号包。过一段时间,收到5号包后,ACK就发生变化,期待6号包。如果5号包没有收到,就先收到了6号包、7号包,那么ACK期望的编号就不会发生变化,总是期望5号包。也就会导致大量的ACK产生。

避免大量ACK产生,发送方如果连续三次接收到重复的ACK,或者超时后没收到任何ACK,就会确认这是产生了丢包,也就是5号包丢失了,从而需要再次发送这个包。通过这个机制,TCP保证了不会有任何数据包丢失(0丢包)。

上一篇:企业微信回调模式验证URL解码失败解决方案


下一篇:经典面试题:浏览器输入 URL 背后发生了什么?(图解版)