计算机网络之TCP

TCP

TCP全名是(Transport Control Protocol),是一个可以提供可靠的、支持全双工、连接导向的协议,因此在客户端和服务端之间传输数据的时候,是必须先建立一个连接的。

怎么理解连接

  1. 是虚拟、抽象的概念,由客户端和服务端程序控制
  2. 能让两个通信的程序间确保彼此都在线
  3. 加快响应请求速度
  4. 连接也被称为会话(Session)
  5. 使通信更稳定、安全
  6. 消耗更多资源

怎么理解全双工

单工:任何时刻数据只能单向发送
半双工:允许数据在两个方向上传输,在某一时刻,只允许数据在一个方向上传输
全双工:任何时刻都能双向发送数据

http虽然是基于TCP的,但不表示http是全双工的协议。事实上,http1.1是半双工协议。虽然TCP可以支持 全双工,但是不等于上层协议一定要支持!

怎么理解可靠性

  1. 可靠性指数据保证无损传输:
  2. 使无序的数据恢复原有顺序
  3. 多播时每个接收方都获得无损副本

三次握手

为什么有有SYN和ACK两个?为什么第二次握手,服务端还需要发送一个SYN信号?SYN和ACK在到底是什么?为什么需要三次握手,两次呢?

首先,SYN和ACK都是TCP头部的标记位,标记这个报文属性,TCP协议有九种不同的标记位。SYN是同步数据信号,即发送数据信号,ACK是响应信号。服务端响应客户端
时,同时也会发送一些数据给客户端,所以也是一次数据同步的过程。需要三次握手的原因是客户端也需要响应服务端的请求,服务端才知道报文被客户端收到了。
在这里插入图片描述

  1. 客户端发送SYN
  2. 服务端准备好进行连接
  3. 服务端针对客户端的SYN给ACK
  4. 服务端发送SYN
  5. 客户端准备就绪
  6. 客户端发送ACK

四次挥手

怎么理解FIN?为什么第二次挥手和第三次挥手不可以跟三次握手一样,一起发?

FIN和ACK一样,是TCP报文九种标记位的其中一种。服务端第二次挥手和第三次挥手没有一起发,是因为服务端接收到客户端的FIN结束信号后,不仅仅要响应客户端,还需要对本次连接做收尾工作,比如关闭服务端响应资源、比如服务端刚给客户端发送了数据,需要等待客户端返回ACK,所以服务端不能发了ACK后马上发FIN。

在这里插入图片描述

TCP从建立连接到断开连接过程

TCP协议为什么需要Seq和ack两种序列号?

试想,客户端给服务端发送消息,给了一个Seq序列号,这时候服务端需要响应客户端,需要发送客户端的序列号+消息数量,但是服务端也会发消息给客户端,这时候就没办法用客户端给的序列号了。因此,客户端和服务端都会有两个序列号,一个表示自己发送的序列号Seq,一个表示告诉对方消息接收到哪里的响应序列号ack。

从图中可以看到,其实SYN报文、ACK报文、PSH报文、FIN报文都是是同时携带ack和seq序列号的。
在这里插入图片描述

TCP数据包

TCP报文包含源端口、目的端口、请求序列号Seq、确认序列号Ack、九种标志位、数据校验等。

16位校验和会对报文数据做单向不可逆的16位编码,这样就可以知道原文有没有发生变化,如果发生变化,就直接丢弃。

16位紧急指针和UCG一起使用的,最常用的是ctrl+c终止程序。给服务端发送终止指令时,本质上也是一个报文,这时候会优先处理UCG包,提前终止程序。
在这里插入图片描述
在这里插入图片描述

TCP拆包

由于应用层数据很可能无法一次传输完成,因此必须拆分大数据包。在TCP头标记当前包的序号,这样在接收端就可以按照顺序恢复消息。
在这里插入图片描述

TCP总结

TCP协议的特点

  1. 连接、双工,可靠性
  2. TCP协议的工作过程(3次握手/4次挥手)和传输数据的过程
  3. TCP头在控制传输过程中的作用
  4. 纠错能力(16位编码校验)、流控能力(滑动窗口)

另外一张关于TCP连接和挥手的状态图

在这里插入图片描述

为什么要三次握手而不是两次

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”,防止了服务器端的一直等待而浪费资源。

第三次握手失败了怎么办

在tcp三次握手中 第二次握手完成后connect 就成功返回了 如果第三次握手的ack包丢了 此时 客户端已认为连接是成功的,如果没有应用层的心跳包,客户端会一直维护这个连接 请问如何避免这种情况?
第二次握手服务器收到SYN包,然后发出SYN+ACK数据包确认收到并且请求建立连接,服务器进入SYN_RECV状态。而这个时候第三次握手时客户端发送ACK给服务器失败了,服务器没办法进入ESTABLISH状态,这个时候肯定不能传输数据的,不论客户端主动发送数据与否,服务器都会有定时器发送第二步SYN+ACK数据包,如果客户端再次发送ACK成功,建立连接。
如果一直不成功,服务器肯定会有超时(大概64s)设置,超时之后会给客户端发**「RTS报文」**(连接重置),进入CLOSED状态,防止SYN洪泛攻击,这个时候客户端应该也会关闭连接。

什么是SYN洪泛攻击

SYN攻击利用的是TCP的三次握手机制,攻击端利用伪造的IP地址向被攻击端发出请求,而被攻击端发出的响应 报文将永远发送不到目的地,那么**「被攻击端在等待关闭这个连接的过程中消耗了资源」** ,如果有成千上万的这种连接,主机资源将被耗尽,从而达到攻击的目的。

为什么要四次挥手

TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。如果要正确的理解四次分手的原理,就需要了解四次分手过程中的状态变化。

四次挥手状态解释

「FIN_WAIT_1」 : 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。「也就是,发出FIN包之后进入FIN_WAIT_1状态」
而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。「也就是,发出ACK报文之后进入FIN_WAIT_2状态」
「主动方FIN_WAIT_2」 :上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接。
「主动方CLOSE_WAIT」 :这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
「被动方LAST_ACK」 : 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。「也就是接收到了对方的FIN包,自己发出了ACK以及FIN包之后的状态」
「被动方TIME_WAIT」 : 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
「主动方CLOSED」 : 表示连接中断。

四次挥手的最后一个状态TIME_WAIT存在的意义

TIME_WAIT状态将持续2MSL,即2倍的报文最大生存时间(每经过一个路由器数值-1,为0时数据包会被丢弃)。在2MSL期间,两边主机的端口不可做它用。

  1. 可靠地实现TCP全双工连接的终止。
    在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允许它重发最终的ACK。
  2. 允许老的重复分节在网络中消逝。
    保证建立新的连接后,前一个连接的数据包在网络中消逝。前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的连接。为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的连接,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时候,来自同ip端口的先前连接的重复分组已经在网络中消逝。

大量TIME_WAIT造成的影响

在高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接。这个场景下会出现大量socket处于TIME_WAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。

解释下什么是短链接:短连接表示“业务处理+传输数据的时间远远小于 TIMEWAIT超时的时间”的连接,业务处理时间1s,而TIME_WAIT持续一分钟甚至几分钟。

如何解决TIME_WAIT造成的影响:如果真的由于并发请求到达了系统资源上线,采用负载均衡的方法可以解决绝大多数应用关于此类的问题。

TCP滑动窗口机制

“窗口”对应的是一段可以被发送的字节序列,其连续的范围称为窗口;2.“滑动”则是指这段“允许发送的范围”是可以随着发送的过程而变化的,方式就是按顺序“滑动”。

是一种流量控制方法,该协议允许发送方在停止等待确认前可以连续发送发个分组。由于发送方不必每发送一个分组就停下来等待确认,因此该协议可以加速数据的传输。

TCP拥塞控制机制

主要包含两个关键点:

  1. TCP利用滑动窗口来实现流量控制机制
  2. 需要考虑传输效率

主要的控制方法:接收端返回的ACK报文会包含自己的接受窗口的大小,以此控制发送段的发送效率。

TCP状态转换图

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值