运输层协议——TCP协议

一. 概述

1. 面向连接:每次使用TCP协议之前,必须建立TCP连接,传送数据完毕后,必须释放TCP连接;

2. 连接只能是点对点(一对一);

3. 提供可靠交付的服务:传送的数据无差错,不丢失,不重复,且按序到达;

4. 全双工通信:通信双方任何时候都能发送数据;TCP连接的双方都设有发送缓存和接收缓存,用于存放通信双方的临时数据;

5. 面向字节流:TCP把应用程序交下来的数据仅看成一连串的无结构的字节流;

补充:TCP连接

1. TCP把连接作为最基本的抽象;

2. 每个TCP连接唯一地被通信双端的两个端点所确定,TCP连接的端点叫做套接字或插口;

3. 套接字:端口号拼接到IP地址即构成了套接字(IP地址:端口号);

二. TCP可靠传输

1. 可靠传输的工作原理

       TCP发送的报文段是交给IP层传送的,但是IP层提供的是尽最大努力服务(不可靠传输),因此运输层必须采取一定措施,才能实现可靠传输。理想的传输条件可以实现可靠传输,主要包括以下两点:

<1> 传输信道不产生差错;

<2> 不管发送方以多大的速率发送数据,接收方总是来得及处理;

       然而,事实上,传输信道总会产生差错,接收方接收数据的速率总是有限的,因此,传输层如果想实现可靠传输,可以在传输信道产生差错的时候重传数据,或者在接收方来不及处理的时候控制发送方的发送速率,来实现可靠传输。

2. 可靠传输协议

       通过可靠传输协议,我们可以在不可靠的传输网络上实现可靠通信。下面介绍自动重传请求(ARQ)协议,意思是重传的请求是自动的,接收方不需要请求发送方重传某个出错的分组。

<1> 停止等待协议(停等协议)

       最简单但也是最基础的可靠传输协议。停止等待就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。

补充:缺点与改进

       停等协议每发送一个分组,就需要停下来等待确认,因此存在信道利用率低的特点。为了提高传输效率,发送方可以不采用停等协议,而是采用流水线传输。发送方可连续发送多个分组,不必每发完一个分组就停下来等,这样子可使信道一直在数据在不间断地传送。

<2> 滑动窗口协议

       发送方和接收方都存在一个窗口,发送方的窗口称为发送窗口,窗口后沿的值表示已经发送完毕,窗口里面的值表示允许发送(有可能已经发送,也有有可能还没发送),窗口前沿的值就不允许发送;接收方也有一个接收窗口,这个窗口的后沿表示已经接收完毕,窗口里面的值表示允许接收(有可能接收,也有可能还没接收),窗口前沿的值就不允许接收。当开始传输数据时,发送方就通过滑动窗口不断发送数据,当接收方收到数据并回复ACK时,发送方就将发送窗口前移,接收方也将接收窗口前移。

补充:发送缓存与接收缓存

1. 发送缓存

<1> 用于存储发送应用程序传送给发送方TCP准备发送的数据;

<2> 用于存储TCP已发送但是尚未收到确认的数据;

2. 接收缓存

<1> 用于存储按序到达,但是尚未被接收应用程序读取的数据;

<2> 用于存储未按序到达的数据;

三. TCP流量控制

1. 控制发送方的发送速率不要太快,让接收方来得及接收;

2. TCP利用滑动窗口实现流量控制;

补充:问题与改进

       当接收方缓存满了导致无法接收数据后,会回复一个零窗口值的接收窗口,此时发送方收到零窗口后,就不会再发送数据了。如果发送方一直不发送数据,则会导致死锁的出现。那么如果解决这个问题呢?答案是持续计时器。TCP为每一个连接设置了持续计时器。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置时间到期,就发送一个零窗口探测报文段(携带1字节数据),而对方在确认这个探测报文段时给出现在的窗口值。如果窗口是0,则收到这个报文段的一方就重新设置持续计时器。如果窗口不是0,那么死锁的僵局就打破了。

四. TCP拥塞控制

1. 拥塞控制的一般原理

<1> 网络资源:计算机网络中的链路容量(带宽),交换结点中的缓存和处理机;

<2> 拥塞:对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏;

<3> 任意增加一些资源,不仅不能解决网络拥塞的问题,甚至可能使网络变坏;

<4> 网络拥塞由很多因素引起。拥塞的实质往往是整个系统的各个部分不匹配,只有所有部分都平衡,问题才能解决;

<5> 拥塞常常趋于恶化。拥塞引起的重传不会缓解网络拥塞,甚至加剧网络拥塞;

2. 拥塞控制的设计思路

<1> 开环控制

设计网络时事先将有关发生拥塞的因素考虑,力求网络在工作中不产生拥塞。运行过程中不会进行改正。

<2> 闭环控制

基于反馈环路的概念,主要有以下几种措施:

监测网络系统以便检测拥塞发生的时间,地点;

把拥塞发生的信息传输到可采取行动的地方;

调整网络系统的运行以解决问题;

3. 拥塞控制的一般方法

       拥塞控制是基于窗口的拥塞控制,它归纳起来就是:慢开始,拥塞避免,快重传,快恢复。发送方维持一个拥塞窗口,并让自己的发送窗口等于拥塞窗口。拥塞窗口的原则是,只要网络没有出现拥塞,拥塞窗口就可以不断增大一些,以提高网络利用率,但如果网络拥塞或可能拥塞,就会缩小拥塞窗口。判断网络拥塞的依据就是出现了超时。

<1> 慢开始

       当主机开始发送数据时,由于不清楚网络的负荷情况,会先探测一下,有小到大逐渐增大拥塞窗口数值。一开始的拥塞窗口会比较小,然后每收到一个对新的报文段的确认后,就把拥塞窗口增加最多一个SMSS的数值。每经过一个传输轮次,拥塞窗口cwnd就加倍。

<2> 拥塞避免

为了防止拥塞窗口cwnd增大而导致网络拥塞,需要设置一个慢开始门限ssthresh:

当cwnd < ssthresh时,使用上述的慢开始算法;

当cwnd > ssthresh时,停止使用慢开始算法而改用拥塞避免算法;

当cwnd = ssthresh时,既可以使用慢开始算法也可以使用拥塞避免算法;

拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加一,而不是慢开始算法那样加倍增大。在拥塞避免阶段,拥塞窗口按线性规律缓慢增大,比慢开始算法的拥塞窗口增大速率缓慢得多。

<3> 快重传

       采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。快重传规定,发送方只要一连收到3个重复确认,就知道接收方确实没收到报文段,因而立即进行重传。这样就不会出现超时,发送方也不会误以为出现了网络拥塞,提高了网络吞吐量(20%)。

<4> 快恢复

       发送方如果知道只是丢失了个别的报文段,就不启动慢开始,而是执行快恢复算法,发送方调整门限值ssthresh=cwnd/2,同时设置拥塞窗口cwnd=ssthresh,并开始执行拥塞避免算法。

       最后,我们需要考虑接收方的接收窗口,并保证发送窗口为拥塞窗口与接收窗口的较小值。

五. TCP运输连接

       TCP运输连接的三个阶段主要包括连接建立,数据传送,连接释放三个阶段。

1. 连接建立(三次握手)

       三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端通过三次交互来确认连接的建立。

<1> 第一次握手

       Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

<2> 第二次握手

       Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

<3> 第三次握手

       Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

补充:SYN攻击

       在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击是一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:netstat -nap | grep SYN_RECV

2. 连接释放(四次挥手)

       四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端通过四次交互以确认连接的断开。

<1> 第一次挥手

       Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

<2> 第二次挥手

       Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

<3> 第三次挥手

       Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

<4> 第四次挥手

       Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

补充:问题与回答

1. 为什么连接的时候是三次握手,关闭的时候却是四次挥手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

2. 为什么TIME_WAIT状态需要经过2MSL(maximum Segment Lifetime)(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

发布了19 篇原创文章 · 获赞 20 · 访问量 5848

猜你喜欢

转载自blog.csdn.net/qq_15898739/article/details/102891297