您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
了解TCP体系结构的详细介绍
 
   次浏览      
 2019-11-26
 
编辑推荐:
本文详细介绍了TCP,包括其基本原理和应用程序体系结构,并讨论了如何使用它来构建高性能服务器。
本文来百度智能甄选,由火龙果软件Alice编辑推荐。

Spring Boot 2.0于2018年初普遍推出,受到许多开发人员的欢迎。默认Web容器是Netty,表示“被动”容器已经是时代的趋势。无论是Go语言的共同依赖线程还是基于Java的反应堆线程模型,它们都是基于事件编程实现高并发性的例子。最初,我想详细介绍NIO,但我意识到在引入NIO之前,有必要了解TCP协议。目前大多数应用程序都在应用程序层上运行,因此隐藏了大量网络细节。了解这些细节和原则有助于排除故障。

TCP功能

TCP是面向连接的协议,为用户进程提供可靠的全双工字节流。通过这种方式,可以确保可靠有序的数据包,并且可以支持流量控制。我们从以下几个方面开始解释TCP应该实现上述操作的原因:

1.IP网络层之所以不能保证数据包的可靠性

2.TCP确保可达和有序数据包的方式

3.TCP支持流量控制的方式

4.TCP状态和应用程序

OSI网络图层

要了解IP网络层不能确保数据包可靠性的原因,让我们先来看一下OSI网络层。在以下层中,TCP位于传输层,这确保了协议的可靠性和连续性。具体的发送和接收数据包由底层链路层和物理层决定,因此TCP的工作也基于底层优化和改进。

客户端和服务器之间的通信使用应用程序协议。传输层的通信使用TCP,而TCP使用较低层IP,IP使用某种形式的数据链路层进行通信。

我们知道网络中的数据最终通过多个路由器连接传输。底层以太网协议规定了电子信号如何形成数据包,解决了局域网(LAN)的点对点通信问题,但无法解决多个局域网的互通问题。

网络层使用的IP协议定义了一组自己的地址规则,主要解决寻址和路由问题,找到根据对方IP地址传输信息的最佳路径。LAN通过路由器连接,路由器根据IP协议指示数据包转发到某个路由接口。但是,IP协议并不能保证数据包的到达和完整性,特别是当网络拥塞时,一些数据包将被丢弃以确保数据传输效率。

为了确保数据包的完整性,有序性和可靠性,这就是TCP即将要做的事情。

深入了解TCP

TCP数据包的组成

许多网络具有最大传输单元(MTU),这是对链路层中的数据帧的限制。例如,MTU通过以太网为1,500字节。IP数据报通过以太网传输。如果其长度大于MTU值,则必须以分片方式传输,以使每个分片的长度小于MTU。

另外,数据包还包含标题信息,除了其自己的TCP标题之外还包括IP标题信息和以太网标题信息。IP数据包在以太网数据包的加载中至少需要20个字节。因此,IP数据包的负载高达1,480字节。

那么,TCP数据包的大小是多少?

这需要MSS值来确定。MSS是TCP中的一个概念(在标题的选项字段中)。MSS是TCP数据包每次可以传输的最大数据段。当TCP数据包的长度大于MSS时,它必须以段的形式传输。如果未设置MSS,则默认值为536字节。也就是说,TCP包大约是500字节。

确保可靠性

如上所述,底层路由器在转发时不能确保数据包的可靠性和有序性。

首先,为了确保数据包的完整性,TCP子包数据包大于基于MSS的MSS。默认MSS为563字节,小于MUT,以便在网络层进行分片。

其次,增加了SEQ和ACK,采用超时重传机制,保证了数据包的可靠性。

SEQ

为了确保分组的有序性,TCP为每个分组分配序列号(SEQ)。这样,接收方可以按顺序恢复分组。在丢包的情况下,还可以知道哪个分组丢失。通常,第一个数据包的SEQ是一个随机数,也可以从1开始。

ACK

既然已经分配了SEQ,那么如何确保包到达?

这是基于ACK确定的。每次接收到数据包时,接收方必须返回ACK,以便发送方可以确认数据包已被传输。此外,接收器必须验证每个数据包。如果在验证期间发现错误,则不发送ACK,从而触发发送方的超时重传。

ACK包含以下信息:

期望接收的下一个数据包的SEQ

接收器接收窗口的剩余容量

我们使用wireshark捕获oschina数据包以查看三次握手数据。

1. me-> osChina:syn = 1 seq = 0 ack = 0

2. osChina-> me:syn = 1 seq = 0 ack = 0 + 1

3. me-> osChina:seq = 0 + 1 ack = 0 + 1

比较三次握手过程。

超时重传

我们知道网络非常不稳定。即使数据包与SEQ和ACK一起添加以确保其有序性,但仍不能保证不会发生丢包或超时问题。如果发送方发送的数据或接收方返回的ACK在网络中丢失或超时,该怎么办?

RTO或重传TimeOut。要确定数据包是否超时,需要一种评估方法。RTT测量给定连接的往返时间。由于网络流量的变化,时间会相应变化。TCP需要跟踪这些变化并动态调整RTO。

如果发送方在一段时间内没有收到数据包的ACK,则可以确定该数据包在网络中丢失并且数据包被自动重传。这种机制称为超时重传。

在此期间,如果发送方没有收到ACK消息,因为来自接收方的消息丢失,则发送方将数据包重新发送给接收方。如果发送方在超时定时器之后收到该数据包的ACK消息,但发送方由于超时已经再次发送了该数据包,则发送方此时不处理ACK而只是丢弃它。接收器收到数据包后再次返回ACK消息。

交通管制

从上面我们知道TCP可以确保数据的可靠性,但它也必须考虑效率。需要考虑以下三个方面:

1.支持批量传输数据包

2.支持基于网络条件的拥塞控制

3.能够理解接收器的状态以防止接收器被淹没

4.基于上述三个要求,采取了以下措施。

滑动窗口

如果TCP数据包逐个传输和确认,则效率太低。尽管确保了可靠性,但是不能确保一次发送和确认一个分组的效率。在这种情况下,需要批量发送和确认方法,这是滑动窗口所做的。

滑动发送窗口:

在发送窗口中,从左到右,此窗口之前的数据必须是接收方已发送和确认的数据,而发送窗口内的数据是发送方可以发送的数据,以及之后的数据发送窗口是无法传输的数据。

如果超时或丢失,建议采用两种解决方案:

去回-N。丢失具有丢失包的SEQ之后的SEQ的所有包

选择ARQ仅传输丢失的数据包,避免重复(效率高,可以防止发送重复的数据包)

滑动窗口还具有让发送者知道接收器的处理状态的功能。假设TCP接收器的缓存已满并且无法处理更多数据,但发件人不知道它。在这种情况下,发送方将不再发送任何数据,只要每次发送分组时发送方被告知当前滑动窗口的大小。

接收器在接收数据后立即发送ACK,但同时向发送器声明窗口大小为0.这样,发送器暂时不会发送数据。

当数据包到达时,不会立即发送ACK,直到缓存中有足够的空间。这可以防止发件人滑动窗口。但是,也存在问题。接收器发送ACK的延迟不应超过超时时间。如果太长,发送方可能会错误地认为数据丢失并重新传输数据。

拥塞控制

我们知道网络状况不稳定。在良好的情况下,可以传输更多的数据包。在不好的情况下,如果传输数据包的速率保持不变,不仅会增加网络负担,还会导致过多的数据包丢失,从而导致更多的超时重传,这无疑会降低通信效率。

基于此,两个TCP通信方保持称为拥塞窗口(cwnd,congesion window)的值,这取决于网络中的拥塞率,并且发送方的Send窗口的值等于拥塞窗口的大小。如果网络中没有发生拥塞,则可以增加拥塞窗口值,以便发送方可以向网络发送更多数据。否则,减少拥塞窗口值以避免增加网络的拥塞率。

TCP目前有以下四种主要的拥塞控制算法:

1.开始慢

2.拥塞避免

3.快速重传

4.快速恢复

没有介绍具体的算法实现。粗略实现的功能是基于当前网络条件找到适当的传输速率以防止网络过载。例如,慢启动意味着开始时传输速度较慢,然后根据数据包丢失调整速率。如果没有丢包,则加速传输速度。如果发生丢包,则传输速度降低。

TCP状态

所有TCP用户都知道,当TCP建立连接时会发生三次握手,并且在断开连接时会发生四次握手。那么状态如何呢?

上面的数字并不太难以记住。让我们看一下下图,将其排序并查看具体的应用程序状态。

如上所示,成功建立连接后,状态为ESTABLISHED。当接收者的状态是SYN-RECV时,它表示接收者已经回复了第二次握手消息,并且正在等待发送者再次确认。如果网络遭受大量SYN攻击,则存在大量SYN_RECV状态。在这种情况下,您可以找到这些IP地址并使用防火墙过滤来解决大量错误连接问题。

丢失连接 - TIME_WAIT

在网络中,一方被主动关闭但未被四方握手关闭。TCP建立的渠道仍然存在吗?关闭多久?此时的TCP状态为TIME_WAIT。可以想象,这种情况经常发生在现实中。大多数封闭连接是主动关闭而不是通过握手通信。如果此时关闭,是否可以重新连接先前的TCP通道?还是需要重新创建?

对于任何TCP实现,必须选择MSL的值。默认值为2分钟或30秒。TIME_WAIT的默认值是MSL的2倍,持续时间介于1到4分钟之间。MSL是IP数据包在网络中生存的最长时间。

存在TIME_WAIT的两个原因:1。终止可靠的TCP全双工连接2.允许旧的重复数据包在网络中消失

TCP必须防止在连接终止之后再现连接的旧重复分组,并且被误解为相同连接的实施例。如果TIME_WAIT足够长,这是MSL的两倍,则允许在某个方向上的数据包在被丢弃之前最多存活一段MSL就足够了。

从TIME_WAIT状态到CLOSED状态,存在超时设置,即2 * MSL(RFC793将MSL定义为2分钟,Linux定义为30秒)。如果时间超过此限制,则将当前TCP通道定义为已关闭。

 

   
次浏览       
????

HTTP????
nginx??????
SD-WAN???
5G?????
 
????

??????????
IPv6???????
??????????
???????
????

????????
????????
???????????????
??????????