前端网络基础-传输层TCP协议

前情回顾

我们已经知道

物理层的作用是将 比特流 转化为 模拟信号,在物理链路中进行传输

数据链路层作用是:1、解封或封装 mac头部(包含源mac和目标mac) 到 数据包中,形成数据帧

2、将数据帧转化为比特流

网络层的作用是:1、通过IP协议,判断目标IP是否和源IP在同一个子网下,即数据包是否要跨网段传输

2、如果要跨网段,则通过路由协议找到最佳路由

3、根据ARP协议获取目标IP主机对应的mac地址,留给数据链路层来封装数据包mac头部

总结得出:网络层工作就是确定好数据包中地址信息,以及确定好数据包的路由信息

数据链路层就是封装mac头,并将数据帧转为数据流,即转发前准备

物理层就是实现数据转发

传输层基本工作任务

传输层作为网络层的上一层,传输层需要为网络层准备好要转发的数据,

传输层也是应用层的下一层,所以传输层还需要将从网络层向上传递的数据转发给应用层对应的应用程序。

所以传输层需要封装发送数据的应用程序的源端口号,以及目的主机上应用程序的目标端口到数据包头部

这可以保证数据能够准确传递给应用层的应用程序。

可靠传输的实现

另外传输层还有一项重要的工作,就是保证数据的完整性,即目标主机可以接收到完整的数据。

由于数据可能很大,传输层会将数据进行分段发送,而分段发送的数据可能会在物理层传输中,发送丢包的现象,导致目标主机无法收到完整数据,此时传输层可以通过TCP协议来保证数据的完整性。

TCP(Transmission Control Prototol)传输控制协议,即该协议会对数据的传输进行一个详细的控制。

TCP报文头格式

传输层会将数据分段发送,在每个数据段的头部会加入一个TCP头部,TCP头部的组成如上图:

除了包含:(当前主机应用程序的)源端口和(目标主机应用程序的)目的端口外,还包含了

序号(seq):该数据段的序号,即将一个较大数据按顺序拆分为多个数据段,并给他们标记序号,当目标主机收到所有数据段后,就可以按序拼接得到原数据。

确认号(ack) : 只有确认消息才有确认号,确认号的作用是期望的下一个数据段的序号,对应请求消息的序号+1,即seq+1

标志位:如图标志位有 URG,ACK,PSH,RST,SYN,FIN,这些标志位只能是0或1,1表示标志位打开,0表示标志位关闭。通过标志位的是否打开,我们可以知道当前TCP报文是什么含义。

ACK标志位打开,表示该TCP报文是一条确认消息

SYN标志位打开,表示该TCP报文是一条请求连接消息,或者确认请求连接消息

FIN标志位打开,表示该TCP报文是一条请求释放连接消息。

RST标志位打开,表示该TCP报文是一条请求释放连接消息,但是和FIN不同,FIN表示请求结束,正常关闭连接,而RST表示服务器出错,强制关闭连接。

TCP三次握手过程

TCP协议是一种面向连接的协议,即想要使用TCP进行通信,则必须先要建立连接。而TCP建立连接的是可信连接,而需要建立可信连接,需要通信双方经过三次握手。

一开始,客户端和服务器都是连接关闭状态,即CLOSED态。之后服务器会立刻进入LISTEN态,实时监听TCP建立连接请求。

然后客户端主动发起TCP请求连接消息到服务器,此时客户端状态变为 SYN_SENT,且请求连接消息中TCP头部的标志位SYN打开,且序号seq=i

服务器收到客户端的请求连接消息后,状态变为syn_received,之后会回复一条确认请求连接消息,在确认消息的TCP头部的SYN和ACK标志位被打开,且ack(确认号)变为 i + 1,表示期望下次发送的下一个序号的数据段,另外当前确认消息也要消耗一个序号,即确认消息也有seq = j

当客户端收到服务器发送的确认请求连接消息后,自身状态变为 established,即建立连接状态,并响应一条 确认连接建立消息,该消息TCP头部的 ACK标志位被打开,且ack= j + 1,表示期望下次响应序号为j+1的数据段,seq = i + 1, 这里seq需要满足上次服务端发送消息的ack期望。

当服务器收到客户端的确认建立连接请求消息后,进入established状态,即建立连接状态

三次握手的优点在于,只有通信双方都确认了连接建立后才能实现通信。

两次握手为什么不能建立TCP连接

思考一下,两次握手能不能实现建立TCP连接,有什么漏洞?

两次握手建立TCP连接,即表示,在服务器发送确认请求连接消息后,服务器立马就进入了established状态,而不管自身发送的确认消息是否被客户端接收到。

如果确认消息因为线路问题在传输过程中丢失了,那么客户端就收不到服务器的确认请求连接消息,也就无法进入established状态,在等待一段时间后,客户端会再次发送一个请求连接消息,但是此时服务器已经认为和客户端建立连接了,而忽略该消息,此时就会产生问题。

而三次握手,避免了该问题。

如果服务器发送确认请求连接消息,并没有被客户端接收到,客户端在等待一段时间后,会再次发送请求连接消息给服务器,服务器收到后,由于自身并没有进入established状态,所以会再次发送一个确认请求连接消息给客户端,当客户端接收到后,客户进入established状态,并进行第三次握手,即发送一个确认建立连接消息给服务器,服务器收到该消息后,才会进入established状态。

通信双方建立TCP连接后,就可以开始互相通信了。

另一种理解思路是:

TCP传输是全双工的,即通信双方的任意一方都可以在发送数据的同时,接收数据。

而这也要求通信双方(发起方和接收方)都具备发送和接收能力。

第一次握手:F  =》S,F发送了,但是F不知道S是否收到了

第二次握手:S =》 F,S回复了,F知道S收到了,但是S不知道F收到回复没

第三次握手:F =》 S,F回复了,S知道F收到回复了

此时F,S都知道对方了具备发送和接收能力了

第三次握手报文丢失

再思考一个问题,如果在客户端发送完第三次握手ACK包后,自身已经进入了established状态,但是第三次握手ACK在传输中丢失了,即服务器没有收到第三次握手消息,那会发生什么?

答:如果第三次握手报文没有到达服务器就丢失了,则服务器会一直处于SYN_RECEIVED状态,并依次等待3s,6s,12s后重新发送【SYN ACK】包给客户端。

但是客户端此时已经是established状态,即自认为TCP连接已建立,而不会理会服务端的【SYN ACK】。

而服务端会发送指定次数的【SYN ACK】包给客户端,如果都没有得到响应,则会关闭当前TCP连接。

而客户端由于自认为TCP连接已建立,所以正常向服务器发送数据报,但是服务器由于没有和客户端建立连接,所以会响应一个RST标志位的释放连接报文,让客户端得知服务端出错,而强制关闭TCP连接。

wireshark抓包演示TCP三次握手过程

下面用wireshark抓包,来说明下TCP建立连接的三次握手

这里 192.168.0.101:55615(客户端) 想和 192.168.0.118:80(服务器) 建立TCP连接

客户端 会发送一个SYN包,且序号seq = 0

服务端接收到该请求连接消息后,会返回一个【SYN ACK】包,并且ack = 1,seq = 0

客户端收到服务端的确认请求连接消息后,会再次发送一个确认建立连接消息【ACK】包,且seq = 1, ack = 1

之后客户端和服务端之间就可以开始通信了

TCP四次挥手过程

而当通信结束了,就需要释放TCP连接,此时客户端和服务端都处于established状态,双方都可以发起释放连接请求报文,我们以客户端主动释放连接,服务端被动释放连接为例

客户端发送一个 请求释放连接报文 给服务端,该报文TCP头部中 FIN标志位被打开(表示请求释放连接),且序号seq = n。

发送后,客户端进入fin_wait_1状态,即半关闭状态,并停止向服务端发送数据报文,但是任然可以从服务器接收数据报文。

服务端收到客户端的请求释放连接消息后,会立刻响应一条 确认请求释放连接(客户端->服务端)报文,报文TCP头部的ACK标志位被打开,确认号ack = n + 1,序号seq = m

且自身状态变为closed_wait,即半关闭状态,此时服务器开始准备释放和客户端之间的连接

客户端收到服务端的确认释放连接消息后,立马进入 fin_wait_2。

此时服务器已经知道了客户端想释放连接,客户端也已经知道了服务端收到了释放连接报文,所以客户端可以确认关闭通向服务器的TCP连接。

服务端在发送完确认释放连接消息后,会经过close_wait阶段,此阶段中会去准备关闭服务端通向客户端的TCP连接,当准备好后,就会发送一个请求释放连接(服务端->客户端)报文,报文TCP头部中FIN标志位被打开,同时也会将ACK标志位打开(和上次确认客户端请求释放连接报文的ACK相同),同时seq,ack也和上次相同。

此时服务端会停止向客户端发送数据报文,但是任然可以接收到客户端发送的报文。

当客户端收到服务端的请求释放连接消息后,会立马发送一条 确认消息 给服务端,该消息TCP头部的ACK标志位被打开,且seq = n+1,ack = m+1,发送后立马进入time_wait_1状态

服务端收到客户端的确认释放连接消息后,立马进入closed状态。

此时服务端关闭了(服务端->客户端)方向的连接。

而客户端在等待一段时间(2MSL)后,自动进入closed状态。

此时客户端关闭了(客户端->服务端)方向的连接。

以上就是TCP四次挥手全过程。

为什么第三次挥手不能和第二次挥手合并

注意:第三次挥手为什么不和第二次挥手合并,因为第二次挥手是为了告诉客户端已经收到请求释放连接的报文了,让客户端可以早点确认可以释放(客户端->服务端)的TCP连接,即遭到进入fin_wait_2。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

核心竞争力,怎么才能提高呢?

成年人想要改变生活,逆转状态?那就开始学习吧~

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处即可领取了

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

性能

linux

前端资料汇总

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处即可领取了

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值