计算机网络分层结构
两种分层结构
OSI体系结构
- 应用层
- 表示层
- 会话层
- 运输层
- 网络层
- 数据链路层
- 物理层
物链网输会示用
TCP/IP体系结构
- 应用层
- 运输层(TCP、UDP)
- 网络层(IP)
- 数据链路层
- 物理层
TCP的三次握手和四次挥手
三次握手
概念
为什么需要握手:握手的作用就是为了同步一些信息,比如最大滑动窗口
TCP:是一个可靠的连接,也就是客户端和服务器双方必须感知对方的存在,也就是需要经历一个建立连接的过程
用三次握手建立TCP连接,连接有三个阶段
- 建立连接
- 数据传输
- 连接释放
连接的管理就是使连接的建立和释放都能正常地进行,连接阶段过程中要解决以下三个问题
- 要使每一方都能确知对方的存在
- 要允许双方协商一些参数
- 能够对运输实体分配资源
TCP连接建立过程
TCP建立连接的过程:被称为握手
① 握手过程其实是发送的TCP报文,在这里面有两个字段,SYN 和 seq
- SYN = 1:表示该报文不能携带数据,但是需要消耗一个SEQ(序号),可以想象成我们对消息编号
- seq:TCP的每个字节发送的时候,都有一个序号,主要是为了保证可靠性,比如当我服务器通过TCP报文得到了有N个字节需要接受,但是最后只接受到了N-1个,我们通过序号就知道哪个没有被接收到。
- 客户端进入SYN_SENT状态,即同步已发送
② 当服务器接受到我们的握手请求时,会回复一个确认报文
- SYN:表示不携带数据,同时消耗一个SEQ = y(这里的y是任意数字,可以是1,2,3,4)
- ACK:=1 表示这是一条确定报文
- ack:x+1,其中x是刚刚客户端发送过来的
- 服务器进入SYN_RECVD状态,即同步已收到
③ 当客户端收到确认报文的时候,客户端需要对这个确认报文进行回复
- ACK:=1,表示这是一条确认报文
- seq:= x +1,
- ack:= y+1
经过了这三次握手,两者就进入了连接状态
为什么是三次握手
四次握手
四次连接有点多余,第三次的时候,我们已经互相进行了连接确认
两次握手:
客户端知道服务器有接收 和 发送的能力,服务器不知道客户端有没有接收数据的能力,因为通过第一次握手,已经知道了客户端能够发送数据,但是能不能接收数据,还是不清楚,因此这个TCP连接是不可靠的。
为什么不能两次握手就建立连接
因为超时重传机制的存在
但客户端发送第一次握手的时候,可能会经历网络拥塞,然后客户端会以为这个连接已经丢失,然后会重新发送一个请求连接的信息到服务器,这次发送的消息很快被服务器接受,然后服务器建立连接就开始建立连接。但是当第一次发送的请求经过一段时间的阻塞后,成功到达服务器,然后服务器又连接连接,而此时客户端是不会理会这次请求的建立,所以服务器一直在等待客户端数据的发送。
四次挥手
所谓的四次挥手,就是关闭TCP连接的过程,指的是断开一个TPC连接,需要客户端和服务端总共发送4个包,以确定双方连接的断开。
主要目的:保证TCP连接的全双工连接
四次挥手示意图
由于TCP连接是全双工的,因此每个方向都必须单独关闭,这个原则是当以防完成它的数据发送任务后,就能发送一个FIN包来终止这个方向的连接。
收到一个FIN包只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后,仍然能发送数据,首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
四次挥手过程
- 第一次挥手:客户端发送一个FIN包(FIN=1,seq=U)给服务器,用来关闭客户端到服务器端的数据传输,客户端进入FIN_WAIT_1状态(终止等待)
- 第二次挥手:服务器端收到FIN包后,发送一个ACK包(ACK=1,ack=u+1,在随机产生一个值v 给seq)给客户端,服务器进入了CLOSE_WAIT状态(关闭等待)
- 第三次挥手:服务器端发送一个FIN包(FIN=1,ACK=1,ack=u+1,在随机产生 一个w值给seq)给客户端,用来关闭服务器到客户端的数据传输,服务端进入了LAST_ACK(最后确定)状态
- 第四次挥手:客户端接收FIN包,然后进入TIME_WAIT状态,接着发送一个ACK包(ACK=1,seq=u+1, ack = w+1) 给服务端,服务端确定序号,进入CLOSe状态,完成了四次挥手。
挥手中的状态
- CLOSED:表示初始状态
- ESTABLISHED:表示连接已经连接
- FIN_WAIT:状态FIN_WAIT_1和FIN_WAIT_2都表示等待对方的FIN报文,这两个状态的区别是,当主动发送方给对方发送了断开请求时,就进入了FIN_WAIT_1状态,而到被动方在回应后,主动发送方就进入了FIN_WAIT_2。
- FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接
- CLOSE_WAIT:这个状态的含义是 表示在等待关闭
- LAST_ACK:在被动关闭放发送FIN报文后,最后等待对方的ACK报文,当收到了ACK报文后,就进入了CLOSE状态。
为什么TIME_WAIT状态还需要等待2MSL后才能返回CLOSE
这是因为虽然双方都同意了关闭连接,而且握手的4个报文也都协调和发送完毕,按道理可以直接回到CLOSE状态
但是因为我们需要假设网络是不可靠的,你无法保证你最后发送的ACK报文是会一定被对方收到,因此处于LAST_ACK状态下的socket可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的报文。
TCP中的流量控制和拥塞控制
流量控制
什么是流量控制
如果发送者发送数据过快,接收者来不及接收,那么就会出现分组丢失,为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。流量控制是针对点到点的。
流量控制的目的是:防止分组丢失,是构成TCP可靠性的一方面。
如何实现流量控制
由滑动窗口协议(连续ARQ协议)实现,滑动窗口协议即保证了分组无差错,有序接收,也实现了流量控制。主要的方式就是接收方返回的ACK会包含自己的接受窗口大小,发送方会根据接收窗口大小调节自己的发送窗口大小,从而实现流量控制。
拥塞控制
什么是拥塞控制
拥塞控制是作用于网络的,它是防止过多的数据注入网络,避免出现网络负载过大的情况,常见的方法就是
- 慢开始,避免拥塞
- 快重传、快恢复
拥塞控制算法
我们首先添加几个限定条件
- 数据是单方向传递,一个窗口发送数据,另一个窗口只发送确认
- 接收方的缓存足够大,因此发送方的大小只由网络的拥塞程度来决定
慢开始算法
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量,拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化,发送方让自己的发送窗口等于拥塞窗口,另外考虑到接收方的接受能力,发送窗口可能小于拥塞窗口。
慢开始算法的思路就是:不要一开始就发送大量的数据,先测探一下网络的拥塞程度,也就是说从小到大主键增加拥塞窗口的大小。
这里用报文段的个数作为拥塞窗口的大小举例说明慢开始算法,实际的拥塞窗口大小是以字节为单位的。如下图所示:
发送方没收到一个确认窗口,就把窗口cwnd加1
从上图可以看到,一个传输轮次所经历的时间其实就是往返时间RTT,而且每经过一个传输轮次,拥塞窗口cwnd就加倍
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量,ssthresh的用法如下:
- 当 cwnd > ssthresh时:使用慢开始算法
- 当cwnd = ssthresh时:采用 慢开始或拥塞避免中的任意一种
- 当 cwnd > ssthresh时:采用拥塞避免算法
拥塞避免算法
拥塞避免算法让拥塞窗口缓慢增长,即没经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样能够让拥塞窗口按线性规律增长。
无论是在慢开始阶段,还是在拥塞控制阶段,只要发送方判断网络出现拥塞,就把慢开始门限 ssthressh设置为当前出现拥塞时发送窗口大小的一半(不能小于2),然后将拥塞窗口cwnd设置为1,执行慢开始算法。
这样做的目的是迅速减少主机发送到网络中的分组数,使得发送拥塞的路由器有足够时间把队列中积压的分组处理完毕。
整个拥塞控制的流程图如下图所示:
- 拥塞窗口cwnd初始化为1个报文段,慢开始门限初始值为16
- 执行慢开始算法,指数规律增长到第4轮,即cwnd=16=ssthresh,改为执行拥塞避免算法,拥塞窗口按线性规律增长
- 假定cwnd=24时,网络出现超时(拥塞),则更新后的ssthresh=12,cwnd重新设置为1,并执行慢开始算法。当cwnd=12=ssthresh时,改为执行拥塞避免算法
乘法减小和加法增大
- 乘法减小”指的是无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半,并执行慢开始算法,所以当网络频繁出现拥塞时,ssthresh下降的很快,以大大减少注入到网络中的分组数。
- 加法增大”是指执行拥塞避免算法后,使拥塞窗口缓慢增大,以防止过早出现拥塞。常合起来成为AIMD算法。
快重传算法
快重传要求接收方在收到一个失序的报文段后,就立即发出重复确定(为的是使发送方及早知道有报文段没有达到对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确定。快重传算法规定,发送方只要一连收到三个重复确定就应当立即重传对方尚为收到的报文段,而不必继续等待设置的重传计时器时间到期,如下所示
快恢复
快重传配合使用的还有快恢复算法,有以下两点要求
- 当发送方连续收到三个重复确认时,就执行乘法减小算法,把ssthresh门限减半(为了预防发送拥塞),但是接下来并不执行慢开始算法
- 考虑到如果网络出现拥塞的话,就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞,所以此时不执行慢开始算法,而是将cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,使cwnd缓慢增大,如下图所示:TCP Reno版本是目前使用最广泛的版本。
在采用快恢复算法时,慢开始算法只是在TCP连接建立时和网络出现超时时才使用
HTTP中的请求类型
- OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性 - HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。 - GET
向特定的资源发出请求。 - POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。 - PUT
向指定资源位置上传其最新内容 - DELETE
请求服务器删除Request-URL所标识的资源 - TRACE
回显服务器收到的请求,主要用于测试或诊断 - CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。