第五章 运输层

本文详细阐述了TCP的端口概念、粘包问题的处理、客户端故障应对、两次握手与三次握手的区别、TIME_WAIT的作用,以及四次挥手过程中的注意事项。深入探讨了TCP的可靠传输机制,包括应答确认、超时重传、快速重传和流量控制。同时讲解了SYN洪泛攻击的原理和防御策略。
摘要由CSDN通过智能技术生成

第五章 运输层

1.什么是端口?

不同的系统使用不同的方法来区分计算机上的应用进程,比如Linux中使用pid,但是怎么使用统一的方式来表示进程?那就是端口。

在这里插入图片描述

在这里插入图片描述

2.分用和复用

在这里插入图片描述

3.TCP粘包及解决方案

4.假如TCP客户端发生故障怎么办?

为了不让服务器白白浪费资源,服务器会用一个保活计时器,每当收到客户端发来的数据,保活计时器就会重新计时。如果超过保活计时器的计时,客户端仍然没有数据发送过来,服务端就给客户端发送探测报文,如果连续十次都没有回复,服务器就认为客户端关闭了。

在这里插入图片描述

5.两次握手可以吗?

​ 不可以。如果使用两次握手的话,当客户端发起连接,收到一次确认后就建立连接。而服务端只要收到客户端发来的请求就变成了建立连接的状态。但是如果客户端第一次发送的请求由于网络延迟没有到达服务端,而且客户端又重新传了一次,立刻到达。这时候,客户端和服务器端交互完数据就断开连接。但是这时候,之前那个由于网络延迟的报文段到达了服务端,服务端又进入了建立连接的阶段。

在这里插入图片描述

6.TIME_WAIT的意义

(1)可靠的终止TCP连接

(2)让网络中的报文都能到达并丢弃。

在这里插入图片描述

TCP概述

TCP,Transmission Control Protocol(传输控制协议)是一种面向连接,可靠的,基于字节流服务的传输层的通信协议。
面向连接:TCP和UDP不同,TCP是面向连接的,关于面向连接,是指通信的双方要先建立连接,然后才能进行数据的读写。这是字节流服务的特点,通信双方的线路是存储在路由器中的。相当于一个“虚电路”。
可靠:TCP通过应答确认和超时重传的机制保证通信是可靠的。TCP是把数据交给IP层,从IP层的角度看,如果网络环境不好,就会出现丢包的情况,这是无法避免的,IP层只是尽自己最大的努力吧数据传输过去,TCP对此也无能为力,只能通过自身的算法来弥补网络环境不好造成的不足。

TCP报文结构

在这里插入图片描述
序号:和确认号两者共同保证TCP的可靠性。序号是建立在传送的字节流之上,而不是建立在传送的报文段之上。通俗的讲就是序号是以字节为单位进行编号,每个字节对应一个字节流编号,这个工作由TCP协议底层完成,我们用户是感受不到的。一个报文段的序号是该报文段首字节的字节流编号。

假设主机A的一个进程想通过一条TCP连接向主机B上的一个进程发送一个数据流,主机A中的TCP将隐式地对数据流中的每一个字节编号。假定数据流由一个包含500 000字节的文件组成,其MSS(最大报文段长度)为1000字节,数据流的首字节编号是0,如下图所示:
在这里插入图片描述
该TCP将为该数据流构建500个报文段,给第一个报文段分配序号0,第二个报文段分配序号1000,以此类推,每一个序号被填入到相应TCP报文段首部的序号字段中

确认号:TCP是全双工的,即主机A在向主机B发送数据的同时,也许也在接收来自主机B的数据。从主机B到达的每个报文段中都有一个序号用于从B流向A的数据。主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号。

例子1:假设主机A已经收到了来自主机B的编号为0-535的所有字节,同时假设它打算发送一个报文段给主机B,主机A等待主机B的数据流中字节536及其后的所有字节,所以主机A会在它发往主机B的报文段的确认号字段中填上536。(即seq + 1)。
例子2:假设主机A已收到主机B的包含字节0-535字节的报文段,以及另一个包含字节900-1000的报文段。由于某种原因,主机A还没有收到字节536-899的报文段。在这个例子里,主机A为了重新构建主机B的数据流,仍在等待字节536(和其后的字节)。因此,A到B的下一个报文段将在确认号字段中包含536。因为TCP只确认该流中到第一个丢失字节为止的字节,所以TCP提供的是累积确认
主机A虽然收到了字节900-1000的报文段,但是并不会在下一个发往主机B的报文段的确认号字段中填1001,因为535后面的字节还没有得到确认,而收到的900-1000字节的报文段属于失序到达,对于失序到达的报文段的处理方法由TCP编程人员去具体实现,有两个基本选择:一是丢弃失序报文段,二是保留失序字节并等待缺少的字节以填补该间隔(这是实践中采用的方法)

标志位
SYN(请求建立连接–synchronous)
FIN (请求断开连接–finish)
RST(重新建立连接–reset 复位报文段
ACK(确认 – acknowledgement)
URG(表示紧急指针域有效–urgent)
PSH(push操作)所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队

RST用来复位TCP连接。当RST=1时,表明TCP连接出现了异常,必须释放连接,然后再重新建立连接。RST置1还用来拒绝一个非法的报文段或拒绝打开一个TCP连接。

紧急标志位URG:取值为1时紧急指针字段有效;取值为0时紧急指针字段无效。紧急指针:占16比特,以字节为单位,用来指明紧急数据的长度。

窗口大小:用来流量控制,指示接收方愿意接受的字节数量。由接收端填充。

4位 头部长度:标识该TCP头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。

16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。

16位紧急指针:是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。

TCP头部选项:TCP头部的最后一个选项字段(options)是可变长的可选信息。这部分最多包含40字节,因为TCP头部最长是60字节

TCP连接的建立与释放

三次握手

1.三次握手的过程

(1)概述:是在底层自动实现的,用户并不会参与,对用户是透明的,但是我们可以通过tcpdump抓包观察这个过程。客户端执行connect(),三次握手开始,connect返回成功,三次握手完成,客户端与服务器端建立连接。connect执行失败,三次握手建立失败。

(2)具体过程
在这里插入图片描述
在这里插入图片描述
第一次握手

  • 客户端发送SYN报文(TCP协议规定SYN=1的报文称为SYN报文,不能携带数据),选择一个初始的序列号为x,这时候client进入SYN_SENT状态。

第二次握手

  • server端接收到client发送的SYN报文,如果同意建立连接,回复一个报文(ACK=1,SYN=1 seq=y,ack=x+1),这个报文也不能携带数据. 这时候,服务端从LISTEN状态转变成了SYN_RECV状态。

第三次握手

  • TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。

三次握手若果完成,客户端的connect成功返回,服务端把连接从未连接状态队列中放到listen的已完成队列中,accept函数从已完成队列中取出已完成的连接,返回描述符。
listen方法用来创建监听队列,监听队列有两种,一种是存放未完成三次握手的连接,一种是存放已经完成三次握手的连接。listen的第二个参数就是指定已完成三次握手的队列的长度(在linux系统上,在unix系统上可能是两个队列的长度之和)。
在这里插入图片描述

accept() 处理存放在listen创建的监听队列中已完成三次握手的连接,每次处理一个连接,accept返回该连接对应的套接字的描述符。如果该队列为空,则accept阻塞。accept是否阻塞取决于监听队列(已完成三次握手的队列)是否为空。也就是说,三次握手完成了,才能执行accept();

2.TCP连接三次握手可以是两次吗?

  不可以,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
  如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

三次握手可以想象两个人在打电话

  • A:喂,能听到吗?
  • B:听得到,你能听到吗?
  • A : 能听到
3.三次握手的抓包

在这里插入图片描述

发送数据的抓包

我们只能看到TCP一般的操作,应答回复是底层自动实现的,我们看不到,所以相对于UDP来说,TCP性能下降了,但是可靠性很高。
在这里插入图片描述

四次挥手

1.四次挥手的过程

(1)图示:
在这里插入图片描述
(2)一般情况下服务器端不主动关闭,当客户端执行close(),此时,客户端发送FIN报文给服务器(序列号为u),服务器接收到此报文之后给客户端进行回应(ack=u+1),然后服务端执行close©,向客户端发送FIN报文(seq=w),客户端收到报文后,回复给服务器ACK报文(ack=w+1).

(3)具体过程

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN_WAIT_1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号

  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE_WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE_WAIT状态持续的时间。

客户端收到服务器的确认请求后,此时,客户端就进入FIN_WAIT_2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

  1. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST_ACK(最后确认)状态,等待客户端的确认。
  2. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME_WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。
2. 为什么客户端最后还要等待2MSL?

第一,可靠的终止TCP连接。保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二保证迟来的报文有足够的时间识别并丢弃。防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。通俗来说就是,因为服务器在发送FIN报文之前还有可能有数据的传送,但是这个报文由于网络原因还没有到达,如果没有TIME_WAIT状态的话,可能客户端(相同的IP和端口)被立即重新启动,当报文到达的时候又会被接收,但是这个报文并不是应该这个客户端接受,应该是上次被关闭的客户端接受。

MSL:是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

3.四次挥手的抓包

在这里插入图片描述

状态转移图

在这里插入图片描述

三次握手期间可能会收到什么样的攻击?

SYN洪泛攻击

概述:服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
例如
在这里插入图片描述

检测:检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

netstat -n -p TCP | grep SYN_RECV 1

常见的防御 SYN 攻击的方法有如下几种:

缩短超时(SYN Timeout)时间
增加最大半连接数
过滤网关防护
SYN cookies技术

引用一篇大佬文章:SYN洪泛攻击

TCP可靠性传输

应答确认

是指每次发送端给接收端发送一段数据m1,接收端收到数据之后会给客户端回复一个ACK报文,表明数据已经收到。在发送方未收到m1的确认信息之前,m1应该保留。直到收到确认信息才能丢弃。
在这里插入图片描述
在这里插入图片描述

超时重传

超时重传是指当发送端发送数据给接收端的时候会设置一个定时器,当超过定时器的时间,仍然没有接收到来自接收端的应答回复,这时候发送端就认为发送的数据没有到达接收端,将会重新发送数据给接收端。
关于没有接收到数据有两种情况:①发送的数据确实没有到达接收端 ②发送的数据到达了接收端,但是接收端回复的ack报文没有到达发送端,这种情况当接收端再次接到同样的报文的时候会丢弃重复的报文。
超时重传最核心的是确定超时重传的时间,这个时间不能过长,因为会导致访问变慢,但也不能过短,因为报文还没传输完成就认为没有到达,重新发送,引起不必要的重传即时间必须大于往返时间(RTT)。
在这里插入图片描述

快速重传

在超时重传中,重点是定时器溢出超时了才认为发送的数据包丢失,快速重传机制,实现了另外的一种丢包评定标准,即如果我连续收到3次dup ACK,发送方就认为这个seq的包丢失了,立刻进行重传,这样如果接收端回复及时的话,基本就是在重传定时器到期之前,提高了重传的效率。

在传输过程中会出现out-of-order的现象,但是在滑动窗口中会有严格的顺序控制,假设有4,5,6三个待接收的数据包,先收到了5,6,协议栈是不会回复对5,6包的确认,而是根据TCP协议的规定,当接收方收到乱序片段时,需要重复发送ACK, 在这个地方会发送报文4 seq的ACK,表明需要报文4没有被接收到,如果此后收到的是报文7,那么仍然要回报文4 seq的ACK如果连续发送3个 dup ACK,接收端认为这个片段已经丢失,进行快速重传。也就是tcp回复的确认号是我下次想接收到的序号。

乱序重排

TCP具有乱序重排的功能。当发送端想接收端发送数据的时候,可能某一条线路堵塞导致先发送的数据可能后到达,对于传输层来说,可能报文顺序乱了,但是传输层会根据报文序号排序,再交给应用层。

流量控制

一般来说,我们希望数据传输的更快一些,不会一次只发一个字节,但是如果太快的话,接收方可能没有足够的时间接收数据,造成数据的丢失。所谓流量控制就是让发送方不要发送的太快,让接收方也有足够的时间接收。TCP利用滑动窗口实现流量控制。

在 TCP 的报头中有一个字段叫做接收通告窗口,这个字段由接收端填充,是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。所以发送端就会有一个发送窗口,这个发送窗口的大小是由接收端填充的接收通告窗口的大小决定的,并且窗口的位置会随着发送端数据的发送和接收到接收端对数据的确认而不断的向右滑动,将之称为滑动窗口。

在这里插入图片描述
在这里插入图片描述
流程:
图片1
在这里插入图片描述
死锁
在这里插入图片描述
死锁的解决

TCP为每一个连接设置一个持续计时器,如果TCP的一端收到另一端的0窗口报文,就是启动持续计时器,让持续计时器时间到的时候,会向另一方发送一个探测报文(携带一字节数据),另一方如果收到之后,会回复自己的窗口状态,如果窗口仍然为0,那么继续启动持续计时器,如果不是0,那么死锁的僵局就可以打破了。

在这里插入图片描述
TCP规定即使接收窗口为0,也要接受确认报文段,零窗口探测报文段,携带有紧急数据的报文段。

rwnd:receive Window 接收窗口

注意点:
在这里插入图片描述

TCP拥塞控制

拥塞控制概念

 拥塞控制也是通过窗口的大小来控制的,前面的滑动窗口rwnd是怕发送方把接收方缓存塞满,拥塞窗口cwnd是怕把网络塞满。(congestion window )

 在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏。这种情况就叫做拥塞(congestion)。
 在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源。
若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。

图示:
拥塞控制描述图
理想状态下的拥塞控制是输入负载等于吞吐量。

TCP拥塞控制算法

  • 慢开始算法
  • 拥塞避免算法
  • 快重传算法
  • 快恢复算法

介绍算法之前,我们假定这些条件:
在这里插入图片描述
慢开始和拥塞避免
在这里插入图片描述

慢开始算法是将拥塞窗口的值指数级增长
拥塞避免算法是将拥塞窗口的值递增增长

图示:
在这里插入图片描述
快重传算法
在这里插入图片描述
在这里插入图片描述
快恢复算法
在这里插入图片描述
四种算法的描述:
在这里插入图片描述
在这里插入图片描述

[粘包及解决方案](

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值