运输层

运输层

从 IP 层来说,通信的两端是两台主机,而运输层通信的两端是应用程序,描述的是应用程序与应用程序的会话

进程之间的通信

从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层

IP 数据报的首部明确地标志了这两台主机的 IP 地址。但真正进行通信的实体是在主机中的进程,是这台主机中的一个进程和另一台主机中的一个进程在交换数据(即通信)

因此严格地讲,两台主机进行通信就是两台主机中的应用进程互相通信。IP 协议虽然能把分组送到目的主机,但是这个分组还停留在主机的网络层而没有交付主机中的应用进程。

从运输层的角度看,通信的真正端点并不是主机而是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。在一台主机中经常有多个应用进程同时分别和另台主机中的多个应用进程通信。

复用和分用

复用:是指在发送方不同的应用进程都可以使用同一个运输层协议传送数据(当然需要加上适当的首部)

分用:是指接收方的运输层在剥去报文的首部后能够把这些数据正确交付目应用进程

与网络层的区别

  • 网络层为主机之间提供逻辑通信,而运输层为应用程序提供端到端的逻辑通信
  • 运输层还要对收到的报文进行差错检测,而网络层只检测 IP 数据报的首部,不检测数据部分

还有一点与网络层不同的是,网络层传送的协议数据单元叫 IP 数据报,而运输层协议传送的协议单元叫 报文段 (UDP 叫用户数据报, TCP 叫报文段)


运输层像高层用户屏蔽了下面网络核心的细节,它使用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道,这条逻辑通信信道对上层的表现却因运输层使用的不同协议而有很大的差别

当运输层采用面向连接的 TCP 协议时,尽管下面的网络是不可靠的,但这种逻辑通信道就相当于一条全双工的可靠信道

但如果采用无连接的 UDP 时,这种逻辑通信信道仍然是一条不可靠的信道

UDP 协议

UDP 是面向数据报的传输层协议 :进程的每个输出操作都会被封装成 UDP 数据报,并组装成一份待发送的 IP 数据报

  • UDP 是不可靠的:它把应用程序传给 IP 层的数据发送出去,但是并不保证它们能到达目的地

  • UDP 是无连接的,发送数据之前不需要建立连接 (无需套接字 Socket)

  • UDP 没有拥塞控制

  • UDP 支持一对一,一对多,多对一,多对多的交互通信

UDP 不关心用护数据的大小,只要应用层发来一份数据,就会封装成一份 UDP 数据报(不管数据有多大,它都会被封装成一个 UDP 数据报)

UDP 首部

每行占四个字节

在这里插入图片描述

源目端口就不解释了, 因为 UDP 是进程之间的通信,必须确定源目端口号

包长度 : UDP 用户数据报的长度 (单位为一个字节),最小值为 8 (UDP 携带的数据允许为奇数,这样需要填入一个全零字节,但是填充的部分并不会发送)

校验和 : 检测 UDP 数据报在传输中是否存在错误, 有错直接丢弃

校验和的计算

与 IP 不同的是, UDP 校验和用于校验整个 UDP 数据报, 而非首部

在计算校验和时,要在 UDP 用户数据报之前临时增加 12 个字节的伪首部(并不是 UDP 数据报的真正首部),校验和就是按照伪首部和真正的 UDP 首部在加上数据一起计算的

在这里插入图片描述

TCP 协议

TCP 是 TCP/IP 体系中非常复杂的一个协议,它是面向数据流的传输层协议,这里的流指的是流入到进程或者从进程流出的字节序列

  • TCP 是面向连接的,是可靠的

    只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费

  • 每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点的

  • TCP 提供全双工通信

    通信中的每一方都在发送和接收报文段

与 UDP 不同的是,TCP 并不关心应用程序一次把多长的报文发送到 TCP 的缓存中,而是根据对方给的窗口值和当前网络拥塞的程度, 来决定一个报文段应该包含几个字节 (UDP 发送的报文长度是应用程序给出的)需要等整个缓存都填满了才上交

如果应用程序传送到 TCP 缓存的数据块太长,TCP 就可以把它划分短一些再传送,如果应用程序只发来一个字节,TCP 先将字节放入缓存,可以等待积累有足够多的字节后再构成报文段发送出去

与 UDP 的区别相当大,它可以进行丢包时的重发控制,还可以对失序乱掉的分包进行顺序控制

TCP 的连接

TCP 连接的端点叫做套接字 (Socket) 或插口, 根据 RFC 793 的定义 : 端口号拼接到 IP 地址即构成了套接字

套接字 Socket = IP地址 :端口号

每一条 TCP 连接唯一地被通信两端的两个端点(即两个套接字)所确定

TCP 连接 ::= {socket1,socket2} = {(IP1 : port1), (IP2, port2)}

这样我们可以得到结论:

有一个 IP 的服务器监听了一个端口, 其 TCP 最大连接数理论上为 65535 个, 但是由于文件描述符和内存限制, 实际上的数量会比这个数小

可靠的运输

我们知道,TCP 发送的报文是需要交给 IP 层运输的,但 IP 层并不保证传输的可靠性,因此 TCP 必须采用适当的措施才能使得两个运输层之间的通信变得可靠

  • 超时重传:当超过一定时间没有收到确认应答就要重传已发送的报文段

    重传时间如何确定?

    TCP 采用了一种自适应算法,过于复杂,我也讲不来

  • 连续收到三次同一个确认应答也会重传

  • 确认应答:当收到报文段后需要向对方回复一个确认

如果收到的报文段无差错,但是未按序号,中间缺少一些序号的数据,TCP 告知发送方只需要发送缺失的数据即可

TCP 首部

同样,每行占 4 个字节

在这里插入图片描述

序列号

用来解决网络包乱序问题, 占 4 字节,序号范围为 0 ~ 2^32 -1,一共 2^32 个序号,在建立连接的时候会初始化一个 ISN 序列号 (初始化的过程相当复杂)

一个 TCP 连接中的字节流的每一个字节都按照顺序编号,整个要传送的字节流的起始序号必须在连接建立时设置。(保证失序乱掉的分包顺序排序)

在发送报文段的时候, 比如初始化序列号为 1000000, 传送的字节流大小为 1000 字节,这些字节的编号就依次为 1000000 ~ 1001000 ,下一报文段应该从 1001001 开始(如果有的话)

确认应答号

期望收到对方下一次报文段的第一个数据字节的序列号, 用来解决不丢包的问题

比如服务器收到一个报文段,其最后一个序列号为 1000000,那么服务器应该回复序号为 1000001 的报文段

总之记住 :若确认号 = N,则说明 :到序号 N - 1为止的所有数据都正确收到

首部长度

同 IP 首部长度, 记录首部长度,如果存在选项字段,就不是默认的 20 字节了

控制位

  1. 紧急 UGR

    当 URG = 1 时,表明紧急指针字段有效,他告诉系统此报文段有紧急数据,应尽快传输,(相当于高优先级的数据),不要按原来的排队顺序来传送

  2. 确认 ACK

    仅当 ACK = 1时确认号字段才有效,当 ACK = 0 时,确认好无效,TCP 规定,在建立连接后所有传送的报文段都必须把 ACK 设为 1

  3. 推送 PSH

    如果收到 PSH = 1 的报文段,就尽快地交付接受应用进程,而不再等到整个缓存都填满后再向上交付,推送操作很少使用

  4. 复位 RST

    当 RST = 1 时,表明 TCP 连接中出现严重差错,必须释放连接,然后重新建立连接

  5. 同步 SYN

    在建立连接时用来同步序号,当 SYN = 1 而 ACK = 0 时,表明这是一个请求连接报文段, 若对方同意连接,则应当在响应的报文段中填入 SYN = 1 且 ACK = 1

  6. 终止 FIN

    用来释放一个连接, 当 FIN = 1 时,表明报文段的发送方的数据已发送完毕,并要求释放运输连接

窗口

占两个字节, 窗口值取值范围为: 0 ~ 65535

窗口值明确指出了无需等待确认应答而可以继续发送数据的最大值,窗口值经常在动态变化着

比如接受方发送了一个报文段,确认号为 10000, 窗口为 2000, 这就意味着,从 10000 号算起, 发送方一次性最多能向接受方回复 2000 个字节 ,不用等待接受方的确认应答(字节序号为 10000 ~ 12000)

总之,窗口相当于接收方的缓存大小

校验和

和 UDP 一样,在计算校验和的时候,要在 TCP 报文段加上 12 字节的伪首部

紧急指针

占 2 字节,紧急指针仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)

选项

长度可变,最大占 40 字节,若不足 4 字节整数倍时,同样需要填充

MSS

TCP 规定了最大报文段长度 MSS,MSS 是每一个 TCP 报文段中的数据字段最大长度(没有加上首部长度),MSS 的默认值时 536,所有在互联网上的主机都能接受的报文段长度是 556 (536 + 20)

理想的情况下, MSS 正好是 IP 中不被分片处理到的最大数据长度 1460 (1500 -20 -20)

TCP 在传送大量数据时,是以 MSS 的大小将数据进行分割发送,重发的时候也是以 MSS 为单位的

MSS 是在三次握手之后,在两端主机之间被计算得出,两端的主机在发出建立连接的请求时,会在 TCP 首部中写入 MSS 选项,告诉对方自己的接口能适应的 MSS 的大小,然后会在两者之间选择一个较小的值投入使用

滑动窗口

TCP 以一个段为单位,每发一个段进行一次确认应答的处理,但这样有一个缺点,就是包的往返时间越长,通信性能越弱,为了避免这个问题,TCP 引入了窗口的概念,即使在往返时间较长的情况下,它也能控制网络性能的下降。

窗口一般为 MSS 的整数倍,滑动窗口是以字节为单位的

在这里插入图片描述

假设在一个段 1000 个字节,窗口为 4 个段的情况下

在上面的情况下,如果收到一个请求序号为 3001 的确认应答,那么 3001 之前的数据就没有必要重发,这部分的数据可以被过滤掉,滑动窗口变为下面的样子

重发控制

确认应答未能返回

在这种情况下,数据已经到达对端,是不需要再进行重发的,然而,在没有窗口控制的时候,没有收到确认应答的数据需要重发,而使用了窗口控制,某些确认应答即使丢失也无需重发

在这里插入图片描述

报文段丢失

在窗口比较大,又出现报文段丢失的情况下,同一需要的确认应答号将会被重复不断的返回,而发送端主机如果连续 3 次收到同一个确认应答,将其所对应的报文段重发

这种机制比之前提到的超时管理更叫高效,因此也叫高速重发控制

TCP 可以表述为一个没有选择确认或否认的滑动窗口协议

TCP 的流量控制

所谓的流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收

使用 滑动窗口机制 可以很方便的在 TCP 连接上实现对发送方的流量控制

TCP 的拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变化TCP 进行拥塞控制的算法有四种

  1. 慢开始
  2. 拥塞避免
  3. 快重传
  4. 快恢复

TCP连接的建立(三次握手)

TCP 建立连接的过程叫作握手,握手需要在客户和服务器之间交换三个 TCP 报文段

在这里插入图片描述

最开始的时候客户端和服务器都是处于 CLOSED 状态,Linux 系统的应用程序调用内核函数 socket 创建了一个套接字,并绑定端口,此时服务进程正在监听连接

  1. 在打算建立 TCP 连接时,客户进程首先初始化一个序列号 seq = x 的报文段,,同时将 SYN 置为 1,当这个报文段发送成功后,客户进程进入了 SYN-SENT 状态

    TCP 规定,该报文段不能携带数据,但是会消耗一个序列号

  2. 服务进程收到请求报文段后,如果同意连接,则发出确认报文段。首先服务进程要为自己随机初始化一个序列号 seq = y ,确认号是 ack = x+1,然后将 ACK, SYN 都置为1, 将这个报文段发送给客户进程之后,服务进程进入了 SYN-RCVD 状态

    同样,该报文段不能携带数据,但会消耗一个序列号

  3. 客户进程收到确认报文段后,还要向服务进程给出确认。客户进程将 ACK 置为 1,确认号是 ack = y+1,序号 seq = x+1,并发送给服务进程。此时,TCP 连接建立,客户进程进入 ESTABLISHED 状态

    TCP 规定,该报文段可以携带数据,如果不携带数据则不消耗序列号

  4. 当服务进程收到客户进程的确认后也进入 ESTABLISHED 状态, 服务端和客户端都会开辟一块资源,用于传输

为什么客户进程最后还要发送一次确认呢?

主要防止已经失效的连接请求报文突然又传送到了服务器,从而导致不必要的错误和资源的浪费。还能帮助双方同步初始化序列号

假设出现这种情况,

  • 客户进程发送了一个请求连接,如果报文段在网络结点中滞留的时间太长了(没有丢失)
  • 客户进程迟迟没有收到确认报文,它就会认为服务进程没有收到请求连接报文
  • 客户进程会再次发送这条报文,此后客户端和服务器完成连接,传输数据,然后关闭连接。
  • 此时之前滞留的那一次请求连接报文,网络通畅到达了服务进程,这个报文本该是失效的
  • 但是,服务进程仍然会认为这是一个新的连接请求,同样会给客户进程回复确认报文
  • 但客户进程根本就不理他,不会回复确认报文,就不会建立连接,节省了资源
  • 但如果采用的是两次握手的机制,那么客户进程和服务进程再次建立连接,这将导致不必要的错误和资源的浪费

TCP连接的释放(四次挥手)

在这里插入图片描述

假设客户进程想要关闭 TCP 连接

  1. 客户进程向服务进程发送连接释放报文段,并停止发送数据,将 FIN 置为 1,序号 seq = u(等于服务进程传送过来的数据的最后一个字节序号加 1),发送成功后,客户端进入 FIN-WAIT-1 状态

    TCP规定,FIN 报文段即使不携带数据,也要消耗一个序号。

  2. 服务进程收到连接释放报文后,发出确认报文段,将 ACK 置为 1, 确认号 ack = u+1,序号 seq = v (等于客户进程传送过来的数据的最后一个字节序号加 1)。发送成功后,服务端就进入了 CLOSE-WAIT 状态,同时向客户发送最后的数据

  3. 客户进程收到服务进程的确认报文后,客户端立刻进入 FIN-WAIT-2 状态,等待服务进程发送最后的数据和连接释放报文段(仍然要接受数据)

  4. 服务进程将最后的数据发送完毕后,还需要发送连接释放报文段,将 FIN,ACK 都置为1,确认号 ack = u+1,序号 seq = w,此时,服务器就进入了 LAST-ACK 状态

  5. 客户进程收到服务进程的连接释放报文后,必须发出确认报文,将 ACK 置为 1,确认好 ack = w+1,序号 seq = u+1,此时,客户进程就进入了 TIME-WAIT(时间等待, Linux 停留在该状态的时间默认为 60 s)状态

  6. 服务进程只要收到了客户进程发出的确认报文段,立即进入 CLOSED 状态。

  7. 客户进程在经过 2 倍的 MSL (最长报文段寿命)后自动进入 CLOSE 状态

    RFC 793 建议将 MSL 设置为 2 分钟,TCP 允许不同的实现可根据具体情况使用更小的 MSL 值

主动关闭连接的, 才有 TIME-WAIT 状态

准确来说叫做两次 FIN 报文段的交换

在服务进程收到客户进程的连接释放报文段后,需要回复确认报文,并发送最后的数据,但如果没有数据呢? 这是有可能的,服务进程直接将第 2,3 次挥手合并成一个报文段发送出去,这样,在连接释放的时候,只存在三次挥手了

所以准确来讲,TCP 连接的释放应该叫做两次 FIN 报文段的交换

为什么 TIME-WAIT 等待时间为2MSL?

第一,保证发送的最后一个 ACK 报文端能够到达对方,因为这个ACK报文可能丢失

第二,在这个 2MSL 时间中,可以防止 ”已失效的连接请求报文段“ 出现在本连接, 可以使本连接持续的时间内所产生的所有报文段都从网络中消失。 这样新的连接中不会出现旧连接的请求报文。

如果已经建立了连接, 但是客户端突然出现了故障怎么办?

TCP 还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。

服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为 2 小时,若 2 小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔 75 秒发送一次。若一连发送 10 个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

SYN 攻击

攻击者在短时间发送给服务端一种伪造不同 IP 地址的 SYN 报文, 服务端每接收到一个 SYN 报文就会回复 ACK + SYN 报文, 并进入 SYN-RCVD 状态, 但是服务器久久无法得到未知 IP 主机的回应, 那么服务端的 SYN 接收队列就会被占满, 使得服务地无法为正常用户服务

如何解决 SYN 攻击?

一种解决方式就是修改 Linux 内核参数, 控制 syn 队列大小和当队列满时应如何处理, 比如缩短 SYN 过期时间, 如果超过这个时间服务器仍然没有收到应答, 则将这个报文丢弃, 可以降低服务器负荷.

还有一种设置 SYN cookies, 给每一个请求的 IP 地址分配一个 cookie, 如果短时间内收到同一个 IP 的重复 SYN 报文, 则以后从这个IP地址发来的包将被丢弃, 这种方式也能应对 SYN 攻击

TCP 和 UDP 的区别?

  1. TCP 是面向连接的传输层协议,传输数据前需要建立连接。 而 UDP 是不需要建立连接就可以传输数据
  2. TCP 面向字节流,而 UDP 面向数据报
  3. TCP 是一对一的关系,而 UDP 是一对一, 一对多,多对一,多对多 的交互通信
  4. TCP 是可靠的, 它保证数据无差错,不丢失,不重复,,按序达到。 而 UDP 不保证可靠交付数据
  5. TCP 有流量控制机制,保证数据传输的安全性。 而 UDP 没有, 即使网络拥堵, 也不应影响发送速率
  6. 首部长度不一致, TCP 不使用选项字段的话,默认为 20 字节,而 UDP 首部固定为 8 字节
  7. UDP 数据报被封装成 IP 数据报后很容易被分片,而 TCP 报文段则不太容易出现分片
  8. UDP 的校验是可选的(大多情况下都是会计算的),而 TCP 的检验和是必需的

两者的应用场景?

TCP 面向连接, 用于可靠性交付, 经常用于 FTP文件传输 和 HTTP / HTTPS.

UDP面向无连接, 可以随时发送数据, 经常用于 包总量较少的通信, 如 DNS, SNMP等, 还用于 视频, 音频的多媒体通信和广播通信.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值