TCP/IP协议

前言

上一篇文章我们提到了OSI参考模型,了解了OSI的七层架构模型。而TCP/IP是在OSI模型的基础上做了一些调整建立TCP/IP协议的五层模型,分别为:应用层(包含OSI的表示层和会话层)、传输层、网络层、数据链路层、物理层。其中网络层TCP/IP只支持IP协议。

协议的重要性

协议就是计算机与计算机之间通过网络通信时,事先达成的一种 “约定”。这种“约定”使不同厂商的设备、不同的CPU以及不同操作系统组成的计算机之间,只要遵循相同的协议就能够实现通信。协议可以比作各个国家的语言,只有同一种语音在沟通时才能相互表达和相互理解。协议分为很多种,每一种协议都明确界定了它的行为规范。两台计算机必须能够支持相同的协议,并遵循相同协议进行处理,这样才能实现相互通信。

TCP/IP协议简介

TCP/IP是个协议群,其中TCPUDP传输协议是TCP/IP协议的核心。

TCP 传输协议

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议,定义了两台计算机之间进行可靠的传输而交换的数据和确认信息的格式,以及计算机为了确保数据的正确到达而采取的措施。协议规定了TCP软件怎样识别给定计算机上的多个目的进程如何对分组重复这类差错进行恢复。协议还规定了两台计算机如何初始化一个TCP数据流传输以及如何结束这一传输。TCP最大的特点就是提供的是面向连接、可靠的字节流服务。

UDP传输协议

UDP(用户数据报协议)是一种面向无连接的、不可靠的、是简单的面向数据报的传输层协议。提供的是非面向连接的、不可靠的数据流传输。UDP不提供可靠性,也不提供报文到达确认、排序以及流量控制等功能。它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。因此报文可能会丢失、重复以及乱序等。但由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

TCP与UDP的区别

TCP报文格式

序号

用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。

确认号

期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。

数据偏移

指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。

保留

占 0.75 个字节 (6 位)。 保留为今后使用,但目前应置为 0。

紧急URG

URG是紧急标志位。当URG=1时,表示紧急指针有效,即此报文时紧急报文优先发送,不再按序发送。此时与后面的紧急指针配合,向后偏移至此报文处,发送此报文。

确认 ACK

当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。

推送 PSH

当 PSH = 1 的时候,表示该报文段高优先级,接收方 TCP 应该尽快推送给接收应用程序,而不用等到整个 TCP 缓存都填满了后再交付。

复位 RST

当 RST = 1 的时候,表示 TCP 连接中出现严重错误,需要释放并重新建立连接。 一般称携带 RST 标志的 TCP 报文段为「复位报文段」。

同步 SYN

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

终止 FIN

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

窗口

窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

TCP连接状态

TCP三次握手

TCP的三次握手是客户端与服务端确认建立连接前发起建立连接请求和相互确认的过程。也是TCP数据可靠的基础,通过三次握手来建立可靠的数据传输通道。

三次握手流程

第一次握手

建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND(发送SYN未收到ACK)状态,等待服务器的确认;

第二次握手

服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECEIVED(已收到对方的SYN,但没有收到自己发送SYN的ACK)状态,等待客户端发送确认;

第三次握手

客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED(已经建立连接)状态,完成TCP三次握手。

为什么要三次握手,而不是一次、两次?

TCP是面向连接的协议,需要确认点对点必须建立在已确认连接的情况下进行通信,如果只是一次握手那么根本不知道对方是否收到或确认连接,发送数据可能会失败,违背了面向连接。

而只有两次握手的情况下,虽然服务端已经发送确认报文,但是并不能保证客户端已经接收到了服务端的确认报文,有可能此时客户端已经下线,如果这个时候就建立连接那么必然会造成资源上的浪费。且为了防止已失效的连接请求报文段突然又传送到了服务端,这种已失效的连接请求如果没有三次握手的话也会造成服务端资源的浪费。

TCP四次挥手

TCP四次挥手是已经好了连接的客户端和服务端,由一端主动发起断开连接请求,被动方进行确认。且被动方也发起断开连接请求,主动方再次确认的过程。在通过双方的相互的确认关闭的机制下,保证了双方数据传输的完整性和安全性。

第一次挥手

客户端(可以是客户端,也可以是服务器端,只是举例),设置Sequence Number,向服务器端发送一个FIN报文段;此时,客户端进入FIN_WAIT_1状态;这表示客户端没有数据要发送给服务器端了;

第二次挥手

服务器端收到了客户端发送的FIN报文段,向客户端回一个ACK报文段,Acknowledgment Number为Sequence Number加1;客户端进入FIN_WAIT_2状态;服务器端告诉客户端,我“同意”你的关闭请求;

第三次挥手

服务器端向客户端发送FIN报文段,请求关闭连接,同时服务器端进入LAST_ACK状态;

第四次挥手

客户端收到服务器端发送的FIN报文段,向服务器端发送ACK报文段,然后客户端进入TIME_WAIT状态;服务器端收到客户端的ACK报文段以后,就关闭连接;此时,客户端等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,客户端也可以关闭连接了。

为什么要四次挥手,而不是两次、三次?

TCP是全双工模式,前两次挥手只是代表客户端没有向服务端发送的数据了,所以客户端发起FIN,服务端ACK。但是这个时候客户端还是能够接收服务端数据的,等到服务端明确没有数据通信了,服务端发起FIN,客户端ACK。所以需要四次挥手,而两次、三次都不能有效保证数据的安全性和完整性。

为什么握手要三次,挥手却要四次呢?

因为在握手的阶段双方还没开始进行数据传输,所以服务端的ACK和SYN报文可以一起发送。而挥手时双方还是可以进行数据传输的,所以服务端只能单独发送ACK确认客户端的断开连接请求,再确认服务端没有向客户端发送的数据后才能发送FIN到客户端。

为什么客户端在第四次挥手后还会等待 2MSL?

因为在第四次挥手时客户端会向服务端发送ACK报文,可能由于网络原因导致了服务端没有收到ACK,那么这个时候服务端在没收到ACK的情况下回再次发送FIN,四次挥手后客户端还要等待2MSL也是为了避免因为网络原因导致服务端没有收到ACK,在等待期间如果继续收到服务端的FIN就继续发送ACK,如果期间没有收到服务端的FIN那么就关闭。

TCP协议如何保证传输的可靠性?

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

校验和

发送方:发送数据之前计算校验和,并填充至TCP报文首部;

接收方:收到数据后,计算检验和,与发送方的校验和比较是否一致,若不一致,则一定传输有误,若校验和一致,也不能说明传输一定成功。若校验出包有错,则丢弃报文段并且不给出响应,这时TCP发送数据端超时后会重发数据;

序列号

1)根据序列号对失序数据包重排序

2)丢弃重复数据:去掉重复序列号的数据;

应答机制

TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答,也就是发送ACK报文。这个确认不是立即发送,通常将推迟几分之一秒;

超时重传

当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;

连接管理

连接管理就是三次握手四次挥手的过程,这是保证可靠性的前提;

流量控制

TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。TCP报文首部有一个窗口,实际上就是接收端接收数据缓冲区的大小。数字越大,证明接收端接收缓冲区的剩余空间越大;接收方收到数据后发送ACK时,会将窗口大小一并发送,发送方根据窗口大小改变发送数据的速度。如果窗口大小为0,那么就停止发送数据。并定期向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端。

拥塞控制

慢启动
  • 开始发送数据时,先发送少量数据探路,观察网络状态,在决定以多打的速度进行传输。这时引入一个拥塞窗口的概念,拥塞窗口初始值为1,每当接收到一个ACK,拥塞窗口就会翻倍,呈现指数级增长。

  • 慢启动机制只是在开始的时候发送少量数据,但是增长速度很快,为了控制拥塞窗口的增长,不能使拥塞窗口单纯的翻倍,要设置一个拥塞窗口的阈值,将慢启动阈值设置为窗口的最大值。

拥塞避免
  • 当拥塞窗口等于慢启动阈值时,就会启用拥塞避免算法。

  • 乘法减小:当出现拥塞时,将慢启动阈值设置为原来的一半,然后将拥塞窗口初始化为1,执行慢启动算法。

  • 加法增大:每经过一个往返时间RTT,拥塞窗口+1,让拥塞窗口缓慢增大,按照线性规律增长。

快重传【对超时重传的改进】
  • 快重传算法要求首先接收方收到一个失序的报文段后就立刻发出重复确认,而不要等待自己发送数据时才进行捎带确认。

  • 接收方成功的接受了发送方发送来的M1、M2并且分别给发送了ACK,现在接收方没有收到M3,而接收到了M4,显然接收方不能确认M4,因为M4是失序的报文段。如果根据可靠性传输原理接收方什么都不做,但是按照快速重传算法,在收到M4、M5等报文段的时候,不断重复的向发送方发送M2的ACK,如果接收方一连收到三个重复的ACK,那么发送方不必等待重传计时器到期,由于发送方尽早重传未被确认的报文段。

快恢复
  • 当发送发连续接收到三个确认时,就执行乘法减小算法,把慢启动开始门限(ssthresh)减半,但是接下来并不执行慢开始算法。

  • 此时不执行慢启动算法,而是把cwnd设置为ssthresh的一半, 然后执行拥塞避免算法,使拥塞窗口缓慢增大。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值