TCP 三次握手和四次挥手
TCP不关心本地send()给自己的内容是啥(反正都是字节),只关心时序,先发给自己的肯定先编号,后发的后编号,TCP本身只保证传输的顺序,至于在服务器端本地、客户端本地的顺序则由Receive()/ Send()时序来保证!
所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包
- 客户端发送一个syn包给服务器,并进入同步已发送(SYN_SEND)状态,等待服务器确认。这个时候SYN=1,seq=x。
- 服务器收到客户端发来的syn包,然后进行确认,同时自己也发送一个SYN+ACK包给客户端,然后服务器进入同步收到(SYN_RECV)状态。这个时候SYN=1,ACK=1,seq=y,ack=x+1。
- 客户端收到服务器的SYN+ACK包后,向服务器发送确认包ACK,这个包发送完毕后,客户端和服务器进入到已建立连接(ESTABLISHED)状态,完成三次握手,开始传输数据。这个时候ACK=1,seq=x+1,ack=y+1。
三次握手的必要性
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
采用二次握手可以吗?
采用三次握手是为了防止失效的连接请求报文段突然又传送到服务器端,因而产生错误。失效的连接请求报文段是指:客户端发出的连接请求没有收到服务器的确认,于是经过一段时间后,客户端又重新向服务器发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,客户端第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到服务器,服务器以为是客户端又发起的新连接,于是服务器同意连接,并向客户端发回确认,但是此时客户端根本不会理会,服务器就一直在等待客户端发送数据,导致服务器的资源浪费
第2次握手传回了 ACK,为什么还要传回 SYN
接收端传回发送端所发送的 ACK 是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传 SYN 则是为了建立并确认从服务端到客户端的通信。”
SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。
四次挥手
过程:
- 当数据传输结束以后,客户端的应用进程发出连接释放报文段,并停止发送数据,其首部:FIN=1,seq=u。客户端进入
FIN_WAIT_1
状态。TCP 规定,即使FIN
包不携带数据,也要消耗一个序号 - 服务器端收到连接释放报文段(FIN包)之后,发出确认报文,其首部:ACK=1,seq=v,ack=u+1。服务器端进入了
CLOSE_WAIT
状态,客户端不再向服务器发送数据。不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务器端发送的ACK
后,进入了FIN_WAIT_2
状态。 - 若服务器已经没有要向客户端发送的数据,其应用进程就通知服务器释放TCP连接。这个阶段服务器所发出的最后一个报文的首部应为:FIN=1,ACK=1,seq=w,ack=u+1。服务器此时进入了
LAST_ACK
状态。 - 客户端收到连接释放报文段之后,必须发出确认包:ACK=1,seq=u+1,ack=w+1。 注意此时 TCP 连接还没有释放,必须经过
2*MSL
((Maximum Segment Lifetime最长报文寿命))后,才进入CLOSED
状态。而服务器端收到客户端的确认包ACK
后就进入了CLOSED
状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。
为什么建立链接协议是三次握手,而关闭链接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
在结束连接的过程中,为什么在收到服务器端的连接释放报文段之后,客户端还要继续等待2MSL之后才真正关闭TCP连接呢?
-
需要保证服务器端收到了客户端的最后一条确认报文。假如这条报文丢失,服务器没有接收到确认报文,就会对连接释放报文进行超时重传,而此时客户端连接已关闭,无法做出响应,就造成了服务器端不停重传连接释放报文,而无法正常进入关闭状态的状况。而等待2MSL,就可以保证服务器端收到了最终确认;若服务器端没有收到,那么在2MSL之内客户端一定会收到服务器端的重传报文,此时客户端就会重传确认报文,并重置计时器。
-
存在一种“已失效的连接请求报文段”,需要避免这种报文端出现在本连接中,造成异常。这种“已失效的连接请求报文段”是这么形成的:假如客户端发出了连接请求报文,然而服务器端没有收到,于是客户端进行超时重传,再一次发送了连接请求报文,并成功建立连接。然而,第一次发送的连接请求报文并没有丢失,只是在某个网络结点中发生了长时间滞留,随后,这个最初发送的报文段到达服务器端,会使得服务器端误以为客户端发出了新的请求,造成异常。
TCP 如何保证可靠性
- 应用数据被分割成 TCP 认为最适合发送的数据块。
- TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
- 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
- TCP 的接收端会丢弃重复的数据。
- 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
- 拥塞控制: 当网络拥塞时,减少数据的发送。
- ARQ 协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
- 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
ARQ 协议
自动重传请求(Automatic Repeat-reQuest,ARQ)是 OSI 模型中数据链路层和传输层的错误纠正协议之一
它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。
ARQ 包括停止等待 ARQ 协议和连续 ARQ 协议。
停止等待 ARQ 协议
它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复 ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组
在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认
优缺点:
- 优点: 简单
- 缺点: 信道利用率低,等待时间长
连续 ARQ 协议。
发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。
滑动窗口和流量控制
TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收
TCP的包可以分为四种状态
- 已发送并且已经确认的包。
- 已发送但是没有确认的包。
- 未发送但是可以发送的包。
- 不允许被发送的包。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率
MSS 最大传输单元-控制数据字段大小
建立连接:确认seq位置 窗口大小
零窗口(TCP Zero Window)
在接收方窗口大小变为0的时候,发送方就不能再发送数据了。但是当接收方窗口恢复的时候发送方要怎么知道那?在这个时候TCP会启动一个零窗口(TCP Zero Window)定时探测器,向接收方询问窗口大小,当接收方窗口恢复的时候,就可以再次发送数据。
拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。
为了避免网络拥塞而采取的对发送方发送速率的控制叫做拥塞控制
为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。
TCP 的拥塞控制采用了四种算法,即 慢开始 、 拥塞避免 、快重传 和 快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生
理论
那 TCP 如何进行拥塞控制呢,每个 TCP 连接的发送方都会去感知网络的拥塞程度,然后去进行拥塞控制,那么 TCP 的发送方是如何感知到当前这个网络存在着拥塞呢,丢包,只要出现了超时就极有可能出现了网络拥堵。那 假设现在出现了网络拥塞,那么 TCP 如何限制传输的速率呢?TCP 的每一端除了维护进行流量控制的滑动窗口外,还会维护一个拥塞窗口(cwnd),拥塞窗口就是对 TCP 发送方的发送速率进行限制的,具体来说的就是 TCP 会控制发送方发送到连接中的但是还没有被接收方确认的数据量,
那我们改变拥塞窗口的大小,就可以调节发送方发送数据的速率。那么发送的速率是多少呢?首先用 rtt 表示一次通信往返所用的时间,那么速率就等于 cwnd/rtt。一般来说 rtt 都是比较固定的,所以调整 cwnd 的值就可以调整发送速率。那我们应该如何确定当前发送速率是多少才合适呢?那就要依靠 TCP 的拥塞控制算法了。拥塞控制算法的实质就是如何来调整 cwnd 的大小。一说到大小就得有衡量单位,那窗口的衡量单位是 mss 最大的传输单元。那我们知道 TCP 分为 TCP 首部和数据两部分,mss 就是去控制数据字段的大小的,那这个值呢是需要通讯双方进行约定的。
cwnd/ rtt = 速率(字节/秒),发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
- 慢开始: 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。
- 拥塞避免: 拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送放的 cwnd 加 1.
- 快重传与快恢复: 如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。 当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作
ssthresh 慢开始的阈值 大于ssshthresh的时候就要采用拥塞避免的算法
拥塞的时候,阈值减半
快重传之后依然要减低阈值,不需要从头开始,从阈值重新开始,省去一个慢开始的阶段即快恢复
从输入URL到页面加载发生了什么
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
get 和 post 有什么区别
GET和POST本质上就是TCP链接,并无差别
但是有两个重要的区别
-
GET把参数包含在URL中,POST通过request body传递参数
GET和POST是什么?HTTP协议中的两种发送请求的方法。
HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
-
GET产生一个TCP数据包;POST产生两个TCP数据包。
长的说:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
HTTP vs HTTPs
HTTP 是一个无状态(stateless)协议,也就是说服务器不维护任何有关客户端过去所发请求的消息。
http通信过程
HTTP 是应用层协议,它以 TCP(传输层)作为底层协议,默认端口为 80. 通信过程主要如下:
- 服务器在 80 端口等待客户的请求。
- 浏览器发起到服务器的 TCP 连接(创建套接字 Socket)。
- 服务器接收来自浏览器的 TCP 连接。
- 浏览器(HTTP 客户端)与 Web 服务器(HTTP 服务器)交换 HTTP 消息。
- 关闭 TCP 连接
HTTPS
HTTPS 是基于 HTTP 的,也是用 TCP 作为底层协议,并额外使用 SSL/TLS 协议用作加密和安全认证。默认端口号是 443.
HTTPS 协议中,SSL 通道通常使用基于密钥的加密算法,密钥长度通常是 40 比特或 128 比特。
SSL/TLS 的工作原理
SSL/TLS 的核心要素是非对称加密。非对称加密采用两个密钥——一个公钥,一个私钥
在通信时,私钥仅由解密者保存,公钥由任何一个想与解密者通信的发送者(加密者)所知。
使用 SSL/TLS 进行通信的双方需要使用非对称加密方案来通信,但是非对称加密设计了较为复杂的数学算法,在实际通信过程中,计算的代价较高,效率太低,因此,SSL/TLS 实际对消息的加密使用的是对称加密。
对称加密:通信双方共享唯一密钥 k,加解密算法已知,加密方利用密钥 k 加密,解密方利用密钥 k 解密,保密性依赖于密钥 k 的保密性。
对称加密的保密性完全依赖于密钥的保密性。在双方通信之前,需要商量一个用于对称加密的密钥。我们知道网络通信的信道是不安全的,传输报文对任何人是可见的,密钥的交换肯定不能直接在网络信道中传输。因此,**使用非对称加密,对对称加密的密钥进行加密,保护该密钥不在网络信道中被窃听。**这样,通信双方只需要一次非对称加密,交换对称加密的密钥,在之后的信息通信中,使用绝对安全的密钥,对信息进行对称加密,即可保证传输消息的保密性
总结
- 安全性和资源消耗 : HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源。
Osi 七层模型
Osi 失败的原因
- OSI 的专家缺乏实际经验,他们在完成 OSI 标准时缺乏商业驱动力
- OSI 的协议实现起来过分复杂,而且运行效率很低
- OSI 制定标准的周期太长,因而使得按 OSI 标准生产的设备无法及时进入市场(20 世纪 90 年代初期,虽然整套的 OSI 国际标准都已经制定出来,但基于 TCP/IP 的互联网已经抢先在全球相当大的范围成功运行了)
- OSI 的层次划分不太合理,有些功能在多个层次中重复出现。
TCP/IP 四层模型
- 应用层
- 传输层
- 网络层
- 网络接口层
应用层
提供两个终端设备上的应用程序之间信息交换的服务,它定义了信息交换的格式,
传输层
负责向两台终端设备进程之间的通信提供通用的数据传输服务
- 传输控制协议 TCP(Transmisson Control Protocol)–提供面向连接的,可靠的数据传输服务。
- 用户数据协议 UDP(User Datagram Protocol)–提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)
网络层(路由和寻址)
负责为分组交换网上的不同主机提供通信服务
网络层的还有一个任务就是选择合适的路由,使源主机运输层所传下来的分株,能通过网络层中的路由器找到目的主机。
网络接口层
- 数据链路层(data link layer)通常简称为链路层( 两台主机之间的数据传输,总是在一段一段的链路上传送的)。数据链路层的作用是将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)。
- 物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异
为什么网络要分层
- 各层之间相互独立
- 提高了整体灵活性
- 大问题化小 :