TCP传输层协议

TCP协议特点:面向连接、字节流、可靠传输
面向连接:
使用TCP协议的双方必须首先建立连接,并且双方都必须分配相应的内核资源。TCP的连接是全双工的,也就是说双方可以根据一个连接进行读写操作。
字节流:
1、当发送方多次写操作的时候,TCP发送模块会先把数据放在发送缓冲区中,当TCP发送模块真正发送的时候,这些在发送缓冲区中的数据才可能被封装成一个或多个报文段发出。所以,应用程序执行的写操作的次数和TCP发送的报文段个数没有对应的数量关系。
2、当接收方收到一个或多个报文段数据后,TCP模块必须把它们携带的应用层数据按照报文段序号放到TCP缓冲区中。同时,通知应用程序读取数据,这样应用程序就可以一次读出数据或者多次读出数据,这取决于应用程序读缓冲区的大小。所以,TCP读取操作的次数跟接收报文段个数也没有固定的关系。
总结:发送端执行的写操作次数与接收端的读操作次数没有任何数量关系,应用程序的发送和接收是没有边界限制的,UDP就不是这样的。
发送端调用的发送次数和接收端的接收次数并不一样。所有的数据都是先进入缓冲区,再进行操作,封装成报文段进行发送和接收。

可靠传输
TCP协议是可靠的传输协议,支持这种可靠传输的机制有:
发送应答机制:发送端发送的每个数据报文段都必须得到接收方的应答。
超时重传机制:发送端在发送报文段数据后,本身就启动计时器,如果在规定时间内没有接到接收端的应答,那么就会重新发送这段数据。

TCP建立连接和关闭连接的过程
SYN:仅在三次握手建立连接时有效,表示同步报文段
ACK:对TCP请求的确认标志
FIN:标志用来结束一个TCP连接,标识此报文段是一个结束报文段

三次握手建立连接
第一次握手:其实是客户端发送一个带有SYN的数据报文段给服务器,就是从主机A到主机B(SYN=1,seq=i),seq为对应序列号i。之后,主机A进入SYN_SEND状态。同时等待服务器的确认。
第二次握手:服务器收到同步报文段后(也就是带有SYN的同步报文段),必须确定客户的同步报文段。然后自己也发送一个带有SYN的报文段,其中SYN=1,表示这是一个同步报文段,ACK=1,表示这是一个确认报文段,确认序号值为i+1,序号值为j。
第三次握手:这次就是客户端收到确认同步报文段后,它向服务器发送确认包,ack=1也就是表示这是一个确认报文段,确认序号为j+1。
三次握手建立后,客户端与服务器开始传送数据。

四次挥手关闭连接
第一次握手:表示客户端A发送给服务器一个带有SYN的结束报文段,用来关闭客户端A到服务端B的数据传送,FIN=1,seq=i,表示一个结束报文段.
第二次握手:服务端B接收到这个结束报文段后,它返回一个确认报文段。其中ACK=1,ack=i+i,表示一个确认报文段,确认序号为i+1.
第三次握手:服务器B关闭与客户端A的连接,他发送一个带有SYN结束报文段,其中 SYN=1,seq=j,表示结束报文段,序号为j。
第四次握手:客户端A返回一个确认报文段,其中确认序号为j+1,ACK=1,ack=j+1。

总结:为什么建立连接需要三次握手?为什么关闭连接需要四次握手?为什么建立连接需要三次握手呢?
接受连接缺需要4次握手,LISTEN状态下建立连接后,它可以把同步报文段和确认报文段合并成一个报文段来进行发送,确认报文段起到应达作用,同步报文段起到同步作用,也就是三次握手中的第二个报文段其实是发挥了两个作用
在关闭连接时,当收到对方的结束报文段时,表示对方没有数据发给你了,但是自己的数据未必全部发送完毕,所以你可能还需要继续发送一些数据之后在发送结束报文段给对方了表示你同意现在可以断开连接,所以关闭连接需要四次握手
如果把三次握手改成两次握手,就有可能发生死锁。

TIME_WAIT状态的含义

在TCP详解(二)中,提到过,当客户端收到服务器的结束报文段后,不会立即进入CLOSED状态,而是转移到TIME_WAIT状态下,在这个状态下,客户端要等待一段2倍的MSL(报文段最大生存时间)时间。等待这个时间后才能完全关闭。TIME_WAIT状态的持续时间是MSL的2倍,这就足以让某个方向上的分组最多存活msl秒即被丢弃,另一个方向上的应答最多存活msl秒也被丢弃。 通过实施这个规则,我们就能保证每成功建立一个TCP连接时。来自该链接先前化身的重复分组都已经在网络中消逝了。

TIME_WAIT状态存在的原因有两点:
可靠的终止TCP连接:
例如在四次握手时,如果第三个报文段丢失,这个时候服务器将重新发送这个报文段,所以客户端需要停留在摸个状态来处理重复信息。否则客户端将会向服务器发送复位报文段,让服务器误认为这是一个错误
保证延迟来的TCP报文段有足够的时间去识别并丢弃:
在Linux系统上,一个TCP端口不能被同时打开多次,当一个TCP连接处于TIME_WAIT状态时,我们将无法立即使用该连接占用的端口建立一个新连接。
但是我们反过来考虑,如果不存在这种机制,那么服务器刚关闭连接,又建立了一个类似的连接,成为“原链接化身”,这个“化身“就有可能就收到属于原来连接的数据报文段,这种情况是不允许出现的。
IME_WAIT状态过多的缺点:
根据上诉,我们可以了解到,如果IME_WAIT状态过多会占用大量的端口号,占用系用资源
IME_WAIT状态过多的处理方法
修改内核参数
尽可能被动关闭连接
将长连接修改为短连接
通过套接字选项尽可能回避IME_WAIT状态带来的负面影响

RST复位报文段
RST复位报文段的作用
曾经在TCP协议详解(一)中介绍了TCP的头部信息,头部中有6位的标识字段,这6位中有一位时RST标志位。如果在TCP某一个报文段中,RST的标志位=1,就说明这个报文段是RST报文段,也就是复位报文段,在某些情况下,TCP连接的一端会像另一端发送携带RST数据报文段,用来通知对方关闭连接或者重新连接。

RST报文段是请求对方连接,发送此报文段的时机有:
在连接建立时
在中间发送数据时
在连接关闭时
以上三种情况都有可能发送RST复位报文段。

发送RST报文段情况
RST复位报文段出现的原因很多,在网路编程中,也很难排查原因在哪?所以列出一些常见的原因,分享给大家:
端口未打开:如果服务器程序端口位打开,而客户端来进行连接。
请求超时:例如一个客户端连接服务器时,Connect系统调用返回时失败,出现错误信息,但是这个时候使用ping命令进行测试没有出现丢包现象,如果在使用抓包工具查看,客户端收到服务器端的同步报文段之后,发送了RST复位报文段,这就有可能是请求超时的原因
提前关闭:如果服务端关闭或者异常终止连接,而且由于网络故障原因,对方没有接收到结束报文段没这个时候客户端还维护着原来的连接,这个时候我们把服务器重新启动,但是次服务器已经没有任何该连接的信息了。如果此时客户端向服务器写一个数据,对方就会回应一个RST复位报文段
在一个已关闭的Socket上收到数据:这种情况看见的不多,比如说连接关闭后,网络中游离的数据包到达目标段,此时目标段发现这个连接已经关闭,复位报文段就会发送到另一个连接。
异常终止一个连接:在数据交换完成之后,发送数据报文段。
向处于LISTEN状态的端口发送数据:会收到对端发送的RST复位报文段

TCP可靠传输机制

TCP超时重传
如果网络异常救出出现超时或者丢包,TCP模块必须能够重传在超时时间内对方未收到的TCP报文段。
TCP模块为每个TCP报文段维护一个重传定时器:该定时器在TCP报文段第一次被发送时启动,如果超时时间内没收到接收方的应答,TCP模块将重传TCP报文段,并重置定时器
如果超时,则进行重传,重新设置定时器
TCP拥塞控制

TCP模块的任务
提高网络利用率
降低丢包率
拥塞控制
其中拥塞控制,还有TCP的流量控制,这种控制机制都是为了TCP的可靠传输设置的,拥塞控制的任务是确保子网能承载所到达的流量。

拥塞控制的最终受控变量是发送端向网络中一次连续写入的数据量,我们称为我们称为发送窗口。不过发送窗口最终以TCP报文段来发送数据,进而发送端口就限定了连续发送的TCP报文段的数量,如图所示,发送窗口被称为SWND,这些报文段的最大长度被称为MSS发送端需要合理的选择发送窗口,如果发送窗口太小,就会出现网络延迟现象,如果发送窗口过大,就容易导致网络拥塞。接收方可以通过接收通告收窗口来控制发送端的发送窗口,但是这看起来也不够,所以在发送端引入一个称为拥塞窗口的状态变量,拥塞窗口简称CWND,接收通告窗口简称RWND。图像中就显示了拥塞控制的闭环反馈控制。

几种拥塞控制的方法:

TCP慢启动
拥塞避免
快速重传
快速恢复

我们知道那个发送端维持一个拥塞窗口的状态变量,拥塞窗口简称CWND,拥塞窗口的大小取决于网络的拥塞程度,并且动态的变化。CWND的处理原则就是只要网络中没有出现拥塞现象,拥塞窗口就在大一些,以便把更多的分组发送出去。只要网络中出现拥塞,拥塞窗口就减少一些。以减少注入到网络分组中的数量。

我们现在来分析拥塞控制的算法:

慢启动:当主机开始发送数据时,如果把大量的字节注入到网络,那么就有可能引起网络拥塞。因为我们现在并不清楚网络的负载情况。所以比较好的方法就是自动去探测一下,由小到大满满增大拥塞窗口的数值,通常在刚刚开始发送报文段的时候,先把拥塞端口设置为一个最大报文段,而在每个在收到新的报文段的时候,把拥塞窗口的大小加1,按照指数规律增长,也就是增大一个最大报文段的数值。我们用同样的方法逐渐增大发送端的拥塞窗口。可以使分组注入到网络中的数据更加合理。

对应到图示中,横坐标从0->3都是满启动的状态。我们为了防止因为增大造成的网络拥塞,我们还需要设置一个满启动的ssthresh值,关于慢启动的ssthresh用法就是如果拥塞窗口小于ssthresh值,就应用慢启动算法。如果拥塞窗口大于ssthresh值,就停止应用慢启动算法。而改用拥塞避免算法

拥塞避免:拥塞避免算法为了让拥塞窗口缓慢的增长,就是每经过一个往返的时间,就把发送方的拥塞窗口加1,而不是成倍增长,这样拥塞窗口是按照线性规律缓慢增长。对应到图像中就是那个明显的拐点以后,都是拥塞避免的算法执行。
仅仅应用 慢启动和拥塞控制,不可能达到控制网络拥塞
接下来介绍快速重传,快速恢复
在很多情况下,TCP发送端都可以接受到重复的确认报文段,例如TCP报文段缺失等等,发送端如果连接接收到三个重复的确认报文段,就可以判断网络中发生了拥塞。这个时候使用快速重传,快速恢复算法。快速重传算法我先要求接受端每收到一个失去的报文到,就立即发送重传确认。
拥塞发生或有三个处理步骤:
拥塞发生后的处理过程:
收到三个重复的确认处理过程:当收到三个重复的报文段时,重新计算满启动的ssthresh值,就是将ssthresh值减半,然后立即重传重传报文段。
收到1个重复确认处理过程:将慢启动的ssthresh值减半后,开始执行拥塞避免算法,而不是刚刚提到的慢启动算法。
收到新数据后的处理过程:重新设置慢启动的ssthresh值,使得拥塞窗口等于当前设置的ssthresh值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值