OSI 7层模型
- 物理层
- 数据链路层
- 网络层
- 传输层
- 会话层
- 表示层
- 应用层
TCP/IP协议 4层模型
- 应用层
- 传输层
- 网络层
- 网络接口层
UDP(用户数据报协议)详解
- UDP是
面向报文
的,没有可靠性控制
,没有拥塞控制
,无连接
,所以其开销小
,但网络环境差或者发送数据过大时导致ip分片过多,导致发送率降低
,影响程序的使用。 - UDP支持一对一、一对多、多对多、多对一通信
-
UDP首部开销小,只有8字节(64bit)
TCP(传输控制协议)详解
- TCP是面向连接的:通信前需要建立连接,结束要释放连接
- TCP是可靠的: TCP发送的数据无重复,无丢失,无错误,与发送端一致
- TCP是面向字节流的:TCP以字节为单位,传输过程中会被划分为一个个数据报, 但接收端最终接受的数据与发送端一样
- TCP提供全双工通信:TCP的两端既可以作为发送端,也可以作为接收端
- TCP只支持一对一通信
- TCP头部有20字节(20*8bit)
- 源端口 和 目的端口 :传输层和网络层一大重要区别就是传输层指定了数据报发往的应用进程,因此需要端口号标识
- 序号:当前TCP数据报数据部分的第一个字节的序号,当前字节在总字节的偏移量,可以给个字节进行编号(大约4G),而且序号循环使用,当发送完个字节后,序号又从0开始。
- 确认号:表示当前主机作为接收端时,期望接收的下一个字节的编号是多少,也表示,当前主机已经正确接收的最后一个字节序号+1
- 4位首部长度:表明了数据报头部的长度
- 保留字段(6位)
- 标识符 (6位)
- URG:当URG字段被置1,表示本数据报的数据部分包含紧急信息,此时紧急指针有效。紧急数据一定位于当前数据包数据部分的最前面,紧急指针标明了紧急数据的尾部。
如control+c:这个命令要求操作系统立即停止当前进程。此时,这条命令就会存放在数据包数据部分的开头,并由紧急指针标识命令的位置,并URG字段被置1
- ACK:ACK被置1后确认号字段才有效,TCP规定,在连接建立后传送的所有报文段都必须把ACK置1
- PSH:当接收方收到PSH=1的报文后,会立即将数据交付给应用程序,而不会等到缓冲区满后再提交
- RST:当该值为1时,表示当前TCP连接出现严重问题,必须要释放重连
- SYN:当SYN=1,ACK=0时,表示当前报文段是一个连接请求报文;当SYN=1,ACK=1时,表示当前报文段是一个同意建立连接的应答报文
- FIN:FIN=1表示此报文段是一个释放连接的请求报文
- URG:当URG字段被置1,表示本数据报的数据部分包含紧急信息,此时紧急指针有效。紧急数据一定位于当前数据包数据部分的最前面,紧急指针标明了紧急数据的尾部。
- 窗口大小(16bit):用于实现TCP的流量控制; 当前
接收方
的接收窗口的剩余容量
,发送方
收到该值后会将发送窗口
调整成该值的大小。发送窗口的大小又决定了发送速率,所以接收方通过设置该值
就可以控制发送放的发送速率
。 发送方每收到一个数据报都要调整当前的发送窗口。 - 校验和(16bit):用于接收端检验整个数据包在传输过程中是否出错
- 紧急指针(16bit):用于标识紧急数据的尾部
- 选项字段 :上述字段都是每个TCP头部必须要有的,而选项字段是可选的,且长度可变,最长40字节。最常用的选项字段为MMS:最大报文长度
TCP三次握手
第一次握手
客户端向服务端发送连接请求报文段。该报文段的头部中SYN=1,ACK=0,seq=x。请求发送后,客户端便进入SYN-SENT状态。
- SYN=1,ACK=0表示该报文段为连接请求报文。
- x为本次TCP通信的字节流的初始序号
TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号
第二次握手
服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1,ACK=1,seq=y,ack=x+1。
该应答发送完成后便进入SYN-RCVD状态
- SYN=1,ACK=1表示该报文段为连接同意的应答报文
- seq=y表示服务端作为发送者时,发送字节流的初始序号
- ack=x+1表示服务端希望下一个数据报发送序号从x+1开始的字节
第三次握手
当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,表示:服务端发来的连接同意应答已经成功收到。
该报文段的头部为:ACK=1,seq=x+1,ack=y+1。
客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接的建立完成!
为什么连接建立需要三次握手,而不是两次握手?
防止失效的连接请求报文段被服务端接收,从而产生错误
若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源
TCP四次挥手
TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。
第一次挥手
若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:
FIN=1,seq=u。此时,A将进入FIN-WAIT-1状态
- FIN=1表示该报文段是一个连接释放请求
- seq=u,u-1是A向B发送的最后一个字节的序号
第二次挥手
B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。此时B进入CLOSE-WAIT状态,并向A发送连接释放的应答,其报文头包含:
ACK=1,seq=v,ack=u+1。
- ACK=1除TCP连接请求报文段以外,TCP通信过程中所有数据报的ACK都为1,表示应答。
- seq=v:v-1是B向A发送的最后一个字节的序号
- ack=u+1表示希望收到从第u+1个字节开始的报文段,并且已经成功接收了前u个字节
A收到该应答,进入FIN-WAIT-2状态,等待B发送连接释放请求
第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。
第三次挥手
当B向A发完所有数据后,向A发送连接释放请求,请求头:FIN=1,ACK=1,seq=w,ack=u+1。B便进入LAST-ACK状态
第四次挥手
A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。
为什么A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态?
为了保证B能收到A的确认应答。
若A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,因此B永远无法正常关闭。
TCP可靠传输实现
- 流量控制、拥塞控制、连续ARQ等技术来保证它的可靠性
停止等待协议(ARQ协议)
ARQ(Automatic Repeat reQuest)自动重传请求。
顾名思义,当请求失败时它会自动重传,直到请求被正确接收为止。这种机制保证了每个分组都能被正确接收。停止等待协议是一种ARQ协议。
停止等待协议的原理
- 无差错的情况
A向B每发送一个分组,都要停止发送,等待B的确认应答;A只有收到了B的确认应答后才能发送下一个分组。 - 分组丢失和出现差错的情况
发送者拥有超时计时器。每发送一个分组便会启动超时计时器,等待B的应答。若超时仍未收到应答,则A会重发刚才的分组。- 分组出现差错:若B收到分组,但通过检查和字段发现分组在运输途中出现差错,它会直接丢弃该分组,并且不会有任何其他动作。A超时后便会重新发送该分组,直到B正确接收为止。
- 分组丢失:若分组在途中丢失,B并没有收到分组,因此也不会有任何响应。当A超时后也会重传分组,直到正确接收该分组的应答为止。
综上所述:当分组丢失 或 出现差错 的情况下,A都会超时重传分组。
- 应答丢失 和 应答迟到 的情况
TCP会给每个字节都打上序号,用于判断该分组是否已经接收。- 应答丢失:若B正确收到分组,并已经返回应答,但应答在返回途中丢失了。此时A也收不到应答,从而超时重传。紧接着B又收到了该分组。接收者根据序号来判断当前收到的分组是否已经接收,若已接收则直接丢弃,并补上一个确认应答。
- 应答迟到:若由于网络拥塞,A迟迟收不到B发送的应答,因此会超时重传。B收到该分组后,发现已经接收,便丢弃该分组,并向A补上确认应答。A收到应答后便继续发送下一个分组。但经过了很长时间后,那个失效的应答最终抵达了A,此时A可根据序号判断该分组已经接收,此时只需简单丢弃即可。
滑动窗口协议(连续ARQ协议)
连续ARQ协议
在ARQ协议发送者每次只能发送一个分组,在应答到来前必须等待。而连续ARQ协议的发送者拥有一个发送窗口,发送者可以在没有得到应答的情况下连续发送窗口中的分组。这样降低了等待时间,提高了传输效率
累计确认
在连续ARQ协议中,接收者也有个接收窗口,接收者并不需要每收到一个分组就返回一个应答,可以连续收到分组之后统一返回一个应答。这样能节省流量。
TCP头部的ack字段就是用来累计确认,它表示已经确认的字节序号+1,也表示期望发送者发送的下一个分组的起始字节号。
发送窗口
发送窗口的大小由接收窗口的剩余大小决定。接收者会把当前接收窗口的剩余大小写入应答TCP报文段的头部,发送者收到应答后根据该值和当前网络拥塞情况设置发送窗口的大小。发送窗口的大小是不断变化的。
发送窗口由三个指针构成:
- p1指向发送窗口的后沿,它后面的字节表示已经发送且已收到应答
- p2指向尚未发送的第一个字节。
p1-p2间的字节表示已经发送,但还没收到确认应答。这部分的字节仍需保留,因为可能还要超时重发。 -
p3指向发送窗口的前沿,它前面的字节尚未发送,且不允许发送
p2-p3间的字节表示可以发送,但还没有发送的字节
接收窗口
接收者收到的字节会存入接收窗口,接收者会对已经正确接收的有序字节进行累计确认,发送完确认应答后,接收窗口就可以向前移动指定字节。
如果某些字节并未按序收到,接收者只会确认最后一个有序的字节,从而乱序的字节就会被重新发送。
流量控制
如果发送者发送过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制
- 流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面
- 滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制
流量控制引发的死锁
当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。
持续计时器
为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。
拥塞控制
拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况
- 缓解网络压力
- 保证分组按时到达
慢开始算法 和 拥塞避免算法
- 发送方维护一个发送窗口,发送窗口的大小取决于网络的拥塞情况和接收窗口的大小,发送窗口是动态变化的。
- 发送方还维护一个慢开始门限
- 发送窗口 < 慢开始门限:使用慢开始算法
- 发送窗口 > 慢开始门限:使用拥塞避免算法
- 发送窗口 = 慢开始门限:使用慢开始算法或拥塞避免算法
算法的具体过程:
- 通信开始时,发送方的发送窗口设为1,并发送第一个分组M1;
- 接收方收到M1后,返回确认应答,此时发送方发送窗口扩大两倍,并发送M2、M3;(即,发送方每次收到确认应答后,都将发送窗口设为当前值的两倍)
- 若发送窗口>慢开始门限,则使用拥塞避免算法,每次收到确认应答后都将发送窗口+1;
- 若发送方出现了超时重传,则表明网络出现拥塞,此时:
a)慢开始门限设为当前发送窗口的一半;
b)发送窗口设为1;
c)启用拥塞避免算法;
注意:发送超时重传时,发送窗口有可能已经超过了慢开始门限,也有可能还没超过;此时不管何种情况,都一律启用拥塞避免算法,并执行上述三步操作!
快速重传 和 快速恢复算法
当接收端收到了3个相同的ACK应答,会启动快速恢复算法
- 把慢开始门限设为当前发送窗口的一半
- 把当前发送窗口设为慢开始门限+3,重传丢失的分组
- 再次收到相同的ACK时,发送窗口大小+1
- 当收到新的ACK时,把当前的发送窗口设为慢开始门限,启用拥塞避免算法
HTTP和HTTPS
HTTP
HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。
HTTP是一个无状态的协议,无状态是指客户机Web浏览器和服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后服务器返回响应(response),连接就被关闭了,在服务器端不保留连接的有关信息
客户机发起一次请求的时候:
- 客户机会将请求封装成http数据包-->封装成Tcp数据包-->封装成Ip数据包--->封装成数据帧--->硬件将帧数据转换成bit流(二进制数据)-->最后通过物理硬件(网卡芯片)发送到指定地点。
- 服务器硬件首先收到bit流....... 然后转换成ip数据包。于是通过ip协议解析Ip数据包,然后又发现里面是tcp数据包,就通过tcp协议解析Tcp数据包,接着发现是http数据包通过http协议再解析http数据包得到数据
HTTPS
HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL。其所用的端口号是443
过程大致如下:
1) SSL客户端通过TCP和服务器建立连接之后(443端口),并且在一般的tcp连接协商(握手)过程中请求证书。
即客户端发出一个消息给服务器,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个数据包,这里面确定了这次通信所需要的算法,然后服务器向客户端返回证书。(证书里面包含了服务器信息:域名。申请证书的公司,公共秘钥)。
2)Client在收到服务器返回的证书后,判断签发这个证书的公共签发机构,并使用这个机构的公共秘钥确认签名是否有效,客户端还会确保证书中列出的域名就是它正在连接的域名。
3) 如果确认证书有效,那么生成对称秘钥并使用服务器的公共秘钥进行加密。然后发送给服务器,服务器使用它的私钥对它进行解密,这样两台计算机可以开始进行对称加密进行通信。