计算机网络知识点总结
计算机网络知识点总结
网络体系结构
5层网络结构
1.应用层
- 作用:定义的是应用进程间的通信和交互规则,针对具体应用,微信,视频等应用程序提供服务
- 数据:常把这一层的数据称为报文
- 常用协议:常用协议如HTTP超文本传输协议,FTP文件传输协议,SMTP简单邮件传输协议,域名系统DNS
2.运输层
- 作用:为两台主机进程之间的通信提供通用的数据传输服务,应用层利用该服务传送应用层报文。通用的是指多种应用可以使用同一个运输层服务,由于一台主机可以同时运行多个进程,因此运输层由复用和分用的功能,复用就是指多个应用层进程可以使用下面运输层的服务,分用与复用相反,指运输层将收到的信息分别交付上面应用层的相应进层
- 数据:这一层数据称为段(报文段/用户数据报)
-
协议:TCP/UDP
- 传输控制协议TCP(Transmission Control Protocol):面向连接的可靠传输,用于传输可靠性要求高的数据,如文件,传输单位为报文段
- 用户数据报协议UDP(User Datagram Protocol):面向无连接的非可靠传输,用于传输可靠性要求不高但实时性要求高的数据,如视频,传输单位为用户数据报
3.网络层
- 作用:选择合适的路由,由于 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路, 也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。 在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。
- 数据:由于网络层使用IP协议,所以分组数据称为IP数据报,简称数据报
- 协议:IP协议,ARP协议
4.数据链路层
-
作用:将网络层交下来的IP数据报组成帧,提供链路访问、差错检测、流量控制、可靠交付等功能 ,
- 链路访问:两台主机之间的数据传输,总在一段一段的链路上传送的,而数据链路层协议可以将网络层交下来的IP数据报组成帧数据从一个节点传递到相同链路的另一个节点上(通过MAC地址)
- 差错控制: 检测所收到的帧中有误差错。如果发现差错,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去白白浪费网络资源。 在接收数据时, 控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。
- 数据:这一层将网络层交下来的IP数据报组成帧,每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制)
5.物理层
- 作用: 它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。 屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。
- 数据:这一层的数据叫做比特。 (比特流–0101等二进制数据)
运输层协议和网络层协议的区别
网络层协议负责的是主机间的逻辑通信
运输层协议负责的是进程间的逻辑通信
IP地址和MAC地址
1、MAC地址( Media Access Control address )应用在OSI第二层,即数据链路层。数据链路层协议可以使数据从一个节点传递到相同链路的另一个节点上(通过MAC地址)。他是不可变的, MAC地址为48位。
2、IP地址应用于OSI第三层,即网络层。网络层协议使数据可以从一个网络传递到另一个网络上(ARP根据目的IP地址,找到中间节点的MAC地址,通过中间节点传送,从而最终到达目的网络)。IP是可以设置的,长度为32位
他们的核心区别是在一个子网络里面(比如一个公司可以有自己的内部网络),MAC 地址可以在这个子网络里面定位到不同的网络设备,IP 可以在整个 internet 中定位到不同的子网络。所以 MAC 是『设备 <-> 设备』,而 IP 是『网络 <-> 网络』。
IP地址和MAC地址在网络中的作用
假设网络上要将一个数据包(名为PAC)由北京的一台主机(名称为A,IP地址为IP_A,MAC地址为MAC_A)发送到华盛顿的一台主机(名称为B,IP地址为IP_B,MAC地址为MAC_B)。这两台主机之间不可能是直接连接起来的,因而数据包在传递时必然要经过许多中间节点(如路由器,服务器等等),我们假定在传输过程中要经过C1、C2、C3(其MAC地址分别为M1,M2,M3)三个节点。
A在将PAC发出之前,先发送一个ARP请求,找到其要到达IP_B所必须经历的第一个中间节点C1的MAC地址M1,然后在其数据包中封装(Encapsulation)这些地址:IP_A、IP_B,MAC_A和M1。当PAC传到C1后,再由ARP根据其目的IP地址IP_B,找到其要经历的第二个中间节点C2的MAC地址M2,然后再将带有M2的数据包传送到C2。如此类推,直到最后找到带有IP地址为IP_B的B主机的地址MAC_B,最终传送给主机B。在传输过程中,IP_A、IP_B和MAC_A不变,而中间节点的MAC地址通过ARP在不断改变(M1,M2,M3),直至目的地址MAC_B。
OSI七层网络结构
OSI对了表示层和会话层,而五层结构将表示层和会话层一并合为应用层
每一层的作用:
- 应用层:为应用程序提供服务
- 表示层:数据格式转换、数据加密
- 会话层:建立、管理和维护会话
- 传输层:建立、管理和维护端到端的连接(段)
- 网络层:负责包从源到宿的传递即IP选择和路由选择(包)
- 数据链路层:提供介质访问和链路管理(帧)
- 物理层:通过媒体介质传输比特(比特)
数据在各层之间的传递过程
从应用层到物理层:
应用层的数据(假设是一个网页),在传输层被分割成许多份(段),每一份在网络层添加上了原ip地址和目标ip地址,变成数据包,然后又加上数据链路层的发送端MAC地址和接收端MAC地址(每一跳都会不断改变),变成数据帧,然后转化为物理层的比特流在物理传输介质上传输。
从物理层到应用层:
另一终端接收到物理层的比特流,先判断数据链路层的接收端MAC地址是不是自己的MAC地址,是的话接收,不是就丢弃,接收后去掉MAC地址部分的数据 ,然后网络层判断目标ip地址是否正确,正确的话去掉ip记录数据,变成数据段,然后由传输层传输,最终在应用层拼接传输层的数据,最终呈现给用户。
为什么要分层
- 解决复杂性:相互通信是两个计算机高度协调的工作,这种协调是复杂的,而分层将一个大问题分割成一个个小问题,简化了网络操作,解决耦合性问题
- 易于实现:标准化各层独立,大问题分割成多个小问题,也更利于实现
- 灵活性好:如果某一层发生变化,只要接口不变,不会影响其他层; 用户只关心用到的应用层,其他层用户可以复用;
- 各层之间相互独立:高层不需要知道底层的功能是采取硬件来实现的,只需要知道通过底层的接口来获得所需要的服务。
TCP和UDP
TCP和UDP的区别和特点
传输控制协议TCP(transmission control protocol)
是面向连接的,提供可靠交付,有流量控制,拥塞控制,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条TCP连接时一对一的用户数据报协议UDP(user datagram protocol)
是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用层传下来的数据不合并也不拆分,只添加UDP首部)支持一对一,一对多,多对一和多对多的交互
- 面向连接与非面向连接,TCP需三次握手后连接,UDP不用连接,适合消息的多播发布,从单个点到多个点
- 可靠与不可靠性,TCP适合可靠的传输,如文件的发送,而UDP适合追求速率而对准确性要求低的传输,如音视频传输
- 拥塞控制:TCP有拥塞控制,UDP没有拥塞控制
- 有序性:TCP通过序列号保证数据的有序交付,而UDP没有序列号,难以保证数据的有序性
- 速度:TCP由于需要建立三次握手等连接,时间花销大,而UDP无需建立,速度快,所以适合实时应用如直播,视频会议
- 连接数:TCP只能是点对点(一对一),UDP可以 一对一、一对多、多对一和多对多的交互通信
- 量级,TCP是中量级,UDP是轻量级,体现在头部大小,TCP是20个字节的头部,而UDP是8个字节的头部
TCP的报文头
- 端口(16位) :源端口和目的端口号表示唯一标识一台主机的进程,即发送数据的端口和接收数据的端口
- 序号(32位):用于对字节流(字节序列)进行编号,比如序号为301,表示第一个字节的编号为301,如果数据长度为100,则下一个报文段的序号为401
- 确认号(32位):期望收到的下一个报文段的序号,比如B正确收到A发送来的一个报文段,序号为501,如果数据长度为100,那么B期望收到的下一个报文段的序号为601,那么B发送给A的确认报文段中的确认号就是601
- 数据偏移(4位):指的是数据部分距离报文段起始处的偏移量,实际就是首部长度,不是20字节吗?
-
控制位(6位):
- 确认ACK:当ACK=1时确认字段有效,否则无效,TCP规定,在建立连接后所有传送的报文段都必须把ACK置1
- 同步SYN:在连接建立时,用来同步序号。当SYN=1,ACK=0时表示这是一个连接请求的报文段,若对方同意建立连接,则响应报文中SYN=1,ACK=1
- 终止FIN:用来释放一个连接,当FIN=1时,表示此报文段的发送方数据已发送完毕,并请求释放连接
- 紧急URG:URG=1为紧急指针有效,为0忽略紧急指针
- 复位RST:用于复位由于主机崩溃或其他原因而出现错误的连接
- 推送PSH:PUSH=1时,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满
- 窗口(16位):窗口值作为接受方让发送方设置其发送窗口大小,之所以有这个设置,是因为接收方的数据缓存空间是有限的
- 校验和(16位):对整个TCP报文段(包括TCP头部和TCP数据)进行计算,其目的是为了发现TCP首部和数据在发送端到接收端的任何改动,如果接收方检测到校验和有差错,则TCP段被丢弃
- 紧急指针(16位):是一个正的偏移量,和序号值相加表示紧急数据最后一个字节的序号
TCP如何保证可靠
- 建立连接:只有通过三次握手建立连接后才开始发送数据,发送数据后需要等待对方确定,才收到确认后再发送下一个数据。
- 数据有序:应用层的报文被分割成TCP认为最适合发送的数据块,并给每个包编号,接收方按照序号对数据包进行排序,然后有序传送给应用层,如果接收方发现中间出现丢包则要求发送方重传
- 确认机制:接收端每接收一个数据段都要向发送端返回一个确认数据段
- 校验和:计算TCP头部和数据的校验和,为了保证数据在发送过程中没有变动,如果收到段的校验和有差错,如收到校验和后进行验证,发现计算结果中的16位中有1位不是1,则丢弃此报文段,否则接收报文段
- 超时重传:当TCP发送一个段后,它会启动一个定时器,等待目的端接收到这个报文段,如果不能在时间内收到回复,则重发这个报文段
- 丢弃重复数据
- 流量控制:根据发送窗口控制发送的速率,保证接收方能来得及接收,减少丢包率。
- 拥塞控制:根据网络情况设置发送窗口,保证网络中的路由器或链路不致过载。
TCP流量控制
TCP利用滑动窗口
实现流量控制,流量控制是为了控制发送方发送速率,保证接收方能来得及接收。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口的带下,从而影响发送方的发送效率。将窗口置为0,则发送方不能再发送数据
滑动窗口
滑动窗口是一种流量控制技术,TCP利用滑动串口来进行传输控制,滑动窗口的大小(窗口大小最大为65535, 2^16 – 1 )意味着接收方还有多大的缓冲区可以用于接收数据,发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为0时,发送方不能再发送数据,但有两种情况除外
- 可以发送紧急数据,例如允许用户终止在远端机上的运行进程。
- 发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。
滑动窗口过大过小的影响
过大:如果窗口过大,则一次发送的数据报太多,容易造成接收端来不及接收(缓存不够)而溢出,并且可能出现 网络拥塞,重传的可能性增大,通信效率变低
过低:极端的情况就是停止等待协议,发送一个字段等一个ACK,需要在网络上频繁的传输确认信息,通信效率也会降低
100M带宽应该设计多大的滑动窗口
带宽:网络带宽是指单位时间内能传输的数据量,100Mb带宽单位为Mb/s,换算成MB/s就是12.5M/s
TCP拥塞控制
在某段时间,对网路中的某一资源需求超过了该资源所能给提供的可用部分,网络的性能就会变坏,这种情况就是拥塞
。拥塞控制是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不至过载。若不进行拥塞控制,那么整个网络的吞吐量将随输入负荷的增大而下降
TCP的四种拥塞控制算法:慢开始,拥塞避免,快重传,快恢复
拥塞控制的过程:
- 发送方维护一个叫
拥塞窗口cwnd
(congestionwindow) 的状态变量,其值取决于网路的拥塞程度,并且动态变化- 拥塞窗口cwnd的维护原则:只要网路没有出现拥塞,拥塞窗口就再增大一些,但只要网路出现拥塞,就将拥塞窗口减少一些
- 判断出现拥塞的依据:没有按时收到应到达的报文(即发生重传)
- 发送方将拥塞窗口取为拥塞窗口和接收方的接收窗口中较小的一个作为发送窗口,即swnd
- 维护一个慢开始门限
ssthresh
状态变量- 当cwnd < ssthresh时,使用
慢开始
算法 - 当cwnd > ssthresh时,停止使用慢开始算法而改用
拥塞避免
算法 - 当cwnd = ssthresh时,既可以使用慢开始算法,也可以使用拥塞控制算法
- 当cwnd < ssthresh时,使用
如何设置ssthresh慢开始门限呢
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(没有按时收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不可小于2个mss)
慢开始:算法思路是当主机开始发送数据时,如果立即把大量数据字节注入到网咯,可能发送网路拥塞,因为刚开始是不知道网络的拥塞情况的,因此需要先用少量数据探测一下,即由小到大的逐渐增大发送窗口,也即是有小到大的逐渐增大拥塞窗口的大小。cwnd初始值为1,每经过一个轮次,cwnd翻倍。
如果当前拥塞窗口cwnd的值已经等于慢开始门限 ssthresh就开始使用拥塞避免算法
拥塞避免:拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把拥塞窗口cwnd的值加1
有时,个别报文段会在网路中丢失,但实际上网络并未发生拥塞,这将导致发送方超时重传,并误认为网络发生了拥塞,发送方会错误的启动慢开始算法,并把拥塞窗口cwnd又设置为1,这样就降低了传输效率。
快速重传:快速重传就是发送方尽快重传接收方未收到的报文段,而不是等待超时重传计时器超时再重传。要求接收方不要等待自己发送数据时才进行确认,而是要立即发送确认;即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。发送方一旦收到3个连续的重复确认,就将相应报文段立即重传,而不是等该报文段的超时重传计时器超时再重传。
对个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以使整个网络的吞吐量提高约20%
快速恢复:发送方一旦收到3个重复确认,就知道只是丢失了个别报文段,于是不启动慢开始算法,而是执行快恢复算法;
- 快恢复算法是将慢开始门限ssthresh值和拥塞窗口值设为当前发送窗口的一半;开始执行拥塞避免算法
- 也有快恢复实现是将快恢复开始时的拥塞窗口cwnd值再增大写,即等于新的ssthresh+3,因为既然发送方收到3个重复确认,就表明3个数据报文段已经离开了网络;因此可以知道报文段减少了3个,可以将拥塞窗口再扩大些
粘包问题
什么是粘包问题
程序需要发送的数据大小和TCP报文段能发送MSS(Maximum Segment Size,最大报文长度)是不一样的, 大于MSS时,而需要把程序数据拆分为多个TCP报文段,称之为拆包;小于时,则会考虑合并多个程序数据为一个TCP报文段,则是粘包;其中MSS = TCP报文段长度-TCP首部长度
网上很多说是TCP粘包,包括面试题中也有TCP粘包,但TCP中没有包这个概念,包是应用层的数据包,TCP是以字节流进行发送的,接收方TCP也是按顺序收到发送方的字节流,之所以会有粘包是因为我们要发送应用层的两个数据包,一个登录数据包data1,一个注销数据包data2,由于TCP流的特性,在接收方会出现以下几种情况
- 先接收到data1,然后接收到data2
- 一次性接收到data1和data2的全部数据
- 先接收到data1的全部数据和data2的部分数据,然后接收到了data2的余下数据
- 先接收到data1的部分数据,然以后接收到data1余下和data2全部数据
对于1这种情况是我们希望见到的,两个数据包分开,而对于2,3,4的情况都是大家锁的粘包问题
,这时就需要对收到的数据进行拆包,拆成一个个独立的数据包,为了拆包就需要在发送端进行封包。
出现粘包的场景:TCP协议下保持长连接
所以归根结底这是应用层的任务
,如何将TCP流中的数据还原成数据包,比如http协议,协议本身有header和body,header里面有Content-Length指定了body大小,接收方就知道接收多少字节后一个数据包的内容结束,就不会出现粘包问题
解决方法
- 给每段数据前加一个2byte的header表示数据的长度(设定65535的大小),比如http协议,在数据前加一个请求头,里面包括Content-length能够知道接收多少算一个数据包结束。前提是能知道报文长度
- 等长数据段收发,每个包就500byte这样收发
- 增加发送延迟(包与包之间的间隔),因为TCP会将数据放在缓冲区的等待一个超时时间,如果在时间内没有后续数据则发送,装满缓冲区为( Maximum Segment Size 1460字节)
- 加入消息分割符
- 如果是HTTP,在可以知道报文长度的情况下,可以使用Content-length,如果不知道则可以使用HTTP/1.1中的Transfer-Encoding:chunked分块传输,chunked由数据长度(16进制)+ 分块数据组成,数据长度为0结束。
UDP会出现上述粘包问题吗
TCP回了保证可靠传输并减少额外开销,采用基于流的传输,因此会出现粘包问题,而UDP则是面向消息传输的,接收方一次只接收一条独立的信息,所以不存在粘包问题
比如我现在有三条数据包,大小分别是2k,4k,6k,如果使用UDP协议发送,不管接收方的缓存区有多大,都需要经历三次接收动作来分别接收三个数据包,而使用TCP协议,我们只需要把缓冲区大小设置为12k以上,我们就能一次把所有数据包都接收下来,只需要一次动作。因此这几个数据包时连在一起的
TCP三次握手
TCP在发送数据前,发送端和接收端会通过三次握手建立连接
为什么要进行三次握手,而不是两次?
为了防止失效的连接请求报文段被服务端接收,从而产生错误。
假设建立连接只需要两次握手,现在客户端向服务器发送连接请求,如果此时网络拥塞,那么客户端发送的连接请求迟迟到不了服务端,客户端便进行超时重发请求,如果服务端接收并确认应答,双方便开始通信(因为只有两次握手),通信结束后释放连接,但是此时那个迟迟到不了的失效连接此时抵达了服务器,由于只有两次握手,那么服务端就又会进入RSTABLISHED状态,等待发送数据或主动发送数据,而此时客户端早已是CLOSED状态,服务端一直等待下去,这样就浪费了服务端资源
如果是三次握手,就算一次失效的报文传送到服务器,服务器接收了那条报文并回复了确认报文,但是客户端不会再次确认,这样服务器收不到确认就认为客户端没有请求连接。
三次握手的过程
第一次,客户端向服务器发送连接请求,等待服务器确认,其中同步标志位SYN=1,假设序列号Seq= 0
第二次,服务器向客户端回送一个响应,通知客户端收到连接请求,返回包包含同步标志位SYN=1,确认收到标志位ACK=1,确认序列号ACKnum=Seq+1,也假设序列号Seq=0
第三次,客户端再次向服务器发送确认信息,确认链接,其中确认标志位ACK=1,ACKnum=Seq+1,序列号Seq=1,确认序列号ACKnum=1
这样就建立了一个全双工的连接,连接建立后就可以发送数据包,在规定时延范围内,对方收到需要发送ACK确认,否则进行重传,其中数据校验使用就校验和来校验数据的完整性
SYN Flood
SYN Flood会伪造SYN报文向服务器发起连接,服务器在收到报文后用ACK应答,此应答发出去后,不会收到ACK报文,造成一个半连接,若攻击者发送大量这样的报文,会在被攻击主机上出现大量半连接,耗尽其资源
,使正常的用户无法访问,直到半连接超时
TCP的四次挥手
TCP终止连接时需要进行四次挥手
四次挥手流程
建立连接后ACK状态都是1,下面是四次挥手的过程:
- Client发送FIN=1,用来关闭Client到Server的数据传送
- Server接收到FIN请求后,发送一个ACK确认,此时TCP属于半关闭状态,Server能给Client发送数据,但Client不能给Server发送数据
- 当Server不再需要连接时,发送一个FIN=1用来关闭Server到Client的数据传送
- Client接收到FIN后给Server发送确认,并进入TIME_WAIT状态,等待2MSL(报文最大生存时间)后释放连接
Server收到确认后释放连接,完成四次挥手
为什么会有超时设置
即TIME-WAIT,等待2MSL,MSL( Maximum Segment Lifetime )报文最大生存时间
- 确保有足够的时间让对方收到ACK包,如果被动关闭方没有收到ACK,就会重发FIN包,这样主动关闭方发送ACK等待,被动方发送FIN,时间一来一去正好是2MSL,如果在2MSL内没有再收到FIN信息,则表明服务端已经关闭了连接,然后客户端关闭连接
- 让旧的报文在网络中消失,不至于影响新的连接。比如现在B给A发送一个FIN释放请求,A做出ACK应答,然后A立即关闭连接,如果这个ACK应答丢失,那么会B等待后会再次发送一个FIN请求,如果此时又有一个新连接用了上述连接的5元素( 源IP,目的IP,TCP,源端口,目的端口 )刚好建立了连接,那么这个迟迟未到的FIN请求达到可能以比较低的概率终止掉连接2
为什么需要四次挥手才能断开连接?
因为连接一旦建立之后就是全双工的,断开连接需要双方都断开,当客户端确认数据发送完且知道服务器已经接收完了,则发送FIN关闭数据口,然后等待服务器确认释放,这一来一回是两次,之后服务器可能会发送完还未传送完的数据
,传送完毕后,服务器也要给客户端发送FIN请求,客户端确认这一来一回又是两次
TIME_WAIT和CLOSE_WAIT的区别在哪
CLOSE_WAIT是被动关闭
形成的,当对方发送FIN报文过来时,回应ACK之后进入CLOSE_WAIT状态,随后检查是否存在未传输数据,如果没有则发起第三次挥手,发送FIN报文给对方,进入LAST_ACK状态并等待对方ACK报文到来
TIME_WAIT是主动关闭
形成的,处于FIN_WAIT_2状态时,收到对方FIN报文后进入TIME_WAIT状态,之后等待两个MSL( Maximum Segment Lifetime:报文最大生存时间 )
UDP
UDP( User Datagram Protocol )即用户数据报协议,它是一种非面向连接的不可靠传输协议,他没有TCP那样的错误重传,窗口控制等精细控制
- 面向非连接,传输不可靠
- 不维护连接,支持同时对多个客户端传输相同消息
- 数据包报头只有8个字节,额外开销小
- 吞吐量只受限于数据生成速率,传输速率以及机器性能
UDP的报文头
- 端口(16位):包括16位源端口和16位目的端口
- 长度(16位):UDP数据报长度,包含UDP报文头和UDP数据长度,UDP报文头长8字节,所以这个值最小为8字节
- 校验和(16位):用于校验数据在传输过程中的完整性
UDP如何变可靠
要实现UDP可靠,先想想TCP如何实现的可靠传输,主要由数据段确认机制、超时重传、有序分段、流量控制等方式
因此,UDP也可以重这几个方面考虑,接收方收到UDP之后也要回复一个确认包,如果发送方收不到确认包就进行超时重传,并且将每个包编上序号,接收方发现中间丢了包就要求发送方重传,当网络太差频繁丢包时,会方式越丢包越重传恶性循环,需要有个发送窗口,根据发送窗口的
既然有了TCP为什么还要UDP可靠
相当于是要兼顾两者的优点,比如TCP是可靠,而UDP是实时性,高效率,并且让UDP去实现更灵活的可靠,因为TCP的可靠性是强制的
HTTP相关
超文本传输协议(HTTP –Hyper Text Transfer Protocol),他是基于TCP/IP协议的应用层协议,不涉及数据包的传输,主要规定了客户端和服务器之间的通信格式。
之所以会比文本多个”超“,是因为它可以将多种文本/图像进行混合,还可以从一个文本跳转到另一个文本
HTTP发展历程
HTTP/0.9
HTTP0.9
只允许客户端发送Get请求,并不支持请求头,只支持纯文本一种类型,服务器只能回应HTML格式字符串,请求格式为
GET /index.html
HTTP/1.0
随着时代的进步,仅仅传输文本无法再满足需求,更多情况需要采用图文的方式才能生动的表达自己的观点,于是诞生了HTTP/1.0
HTTP1.0
这个版本中,有以下特点
- 可以发送任何格式的文件,使互联网不仅可以传输文字,还可以传输图像,音频,视频等二进制文件;
- 支持GET,POST和HEAD等请求方法
- 加入协议版本号,同时添加文件处理类型
- 加入HTTP头部, 让HTTP处理请求更加灵活
- 增加了响应状态码(status code)、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)
- HTTP1.0版本虽然支持长连接,但默认还是短连接,需要使用keep-alive参数来告知服务器建立一个长连接。短连接的缺点就是每个TCP连接智能发送一个请求,发送和响应完毕,连接就会关闭,如果怕需要请求其他资源就需要重新创建一个连接,TCP的链接成本是很高的,因为需要三次握手,因此HTTP1.0版本性能较差,虽然keep-live可以建立一个长连接,但这不是一个根本的办法
GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html> <body>Hello World</body> </html>
HTTP/1.1
随着文件越来越大,图片等信息越来越复杂,如果每一次上传下载都需要建立连接,那么开销是巨大的,为此引入了长连接的HTTP/1.0
HTTP1.1
最大的变化就是引入了keepalive长连接,也就是TCP默认连接是不关闭,可以被多个HTTP请求复用,客户端或服务器如果长时间发现对方没有活动就关闭连接,规范做法是客户端在最后一个请求的时候要求服务器关闭连接,对于同一个域名,浏览器支持建立6个长连接。
HTTP1.1新增的主要点:
- 新增keepalive长连接,允许TCP连接被多个请求复用
- 支持 pipeline,无需等待前面的请求响应,即可发送第二次请求 ,主要是解决Head of line blocking队头阻塞问题
- 响应数据分块(chunked),对响应的报文进行编码传输,直到收到服务端的 EOF,利于传输传输文件大小未知、文件大小仍在动态增长的文件。 分块传输是因为响应的报文长度经常是不可预测的,使用Content-length对实体捕获并不总是管用,这时分块传输的优势就体现了,他利于
传输文件大小未知、文件大小仍在动态增长以及一些大文件
的传输 - 新增缓存的控制和管理。
- 加入了 Host 头,用在你一台机子部署了多个主机,然后多个域名解析又是同一个 IP,此时加入了 Host 头就可以判断你到底是要访问哪个主机。
head of line blocing问题
即队头阻塞问题,在HTTP1.0中,当有多个请求需要发送时,如果前一个请求没有得到回复,那么后续的请求会进行排队,等待前一个请求得到响应,这样一来后面的请求就被阻塞了,影响了传输效率。
因此在HTTP1.1中引入了pipeline管线化技术,允许客户端不用等待服务器的响应就能发送下一个请求,目的是为了在一次TCP连接上可以并行发送多个请求,来提高网络利用率,但是他依然有一个很大的缺点,就是服务器必须按照请求的顺序来响应,即后续请求的响应必须等待第一个响应发送之后才能发送,即使后续响应已经完成。因此HTTP1.1中依然存在队头阻塞的问题。
在HTTP2.0中彻底解决了这个问题。
为什么要有Connection: keep-alive?
在早期的HTTP/1.0中,每次http请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重用连接。在后来的HTTP/1.0中以及HTTP/1.1中,引入了重用连接的机制,就是在http请求头中加入Connection: keep-alive来告诉对方这个请求响应完成后不要关闭,下一次咱们还用这个请求继续交流。协议规定HTTP/1.0如果想要保持长连接,需要在请求头中加上Connection: keep-alive,而HTTP/1.1默认是支持长连接的,有没有这个请求头都行。
HTTP分块传送
分块传送是HTTP的一种传输机制,允许服务端发送给客户端的数据分为多个部分,该协议在HTTP/1.1上提供
分块传送的好处
利用分块传输可以像知道Content-Length那样避免粘包问题,同时由于是分块传输,所以有利于传输文件大小未知或者文件大小动态增长的数据
HTTP/2.0
HTTP/2.0的出现,相比于HTTP/1.x大大提高了Web性能,
HTTP/2.0版本主要增加以下几点:
- 二进制分帧:在应用层和传输层之间增加二进制分帧层
- 多路复用:支持一个TCP连接发起多个请求,移除pipeline
- 服务器主动推送:允许服务器向客户端主动推送数据
- 头部压缩:利用HPACK压缩头部,减少数据传输量
二进制分帧 :HTTP/2.0突破HTTP/1.1性能限制的关键在于在应用层和传输层之间增加一个二进制分帧层,,使用二进制传输,在HTTP1.x中我们是通过文本方式传输数据的,而文本传输存在很多缺陷,文本的表现形式有多样性,因此要做到健壮性考虑的场景必然有很多,但是二进制则不同,只有0和1的组合,因此选择了二进制传输,实现方便且健壮。
在二进制分帧层中,HTTP/2会将所有传输的信息分割为更小的消息和帧(frame),并对他们采用二进制格式的编码,其中HTTP1.x 的首部信息会被封装到HEAER frame中,而相应的Request Body会被封装到DATA frame内部。
支持一个TCP连接发起多个请求:即支持多路复用, 像 HTTP/1.1 pipeline 本质上也是multiplexing,虽然目的是解决head of line blocking ,但依然存在很多问题,如只有幂等的GET和HEAD才能使用pipelining,非幂等请求POST不能使用,因为请求之间会存在先后依赖关系,并且head of line blocking并没有完全解决.
这种单连接多资源的方式,减少了服务器的连接压力,内存占用更少,连接吞吐量更大,同时由于TCP连接的减少,网络有拥塞情况也有所改善,慢启动时间减少,拥塞和丢包恢复更快。
HPACK压缩头部:采用了静态表、动态表和哈夫曼编码
服务端主动推送数据:其实就是减少了请求次数,比如客户端请求1.html,我就把相关的js和css一起传送过去
HTTP2.0的帧
HTTP/3.0
HTTP/3的改动主要是针对TCP的一些弊端而进行改进
-
TCP自带慢启动
慢启动可能会带来性能问题,比如一个页面有静态数据,动态页面,很多小文件在加载过程中就会直接发起请求,这样导致太多的请求都会经历慢启动过程,花费时间太多
-
头部阻塞
阻塞,在网络编程中,一般采用异步,多路复用(epoll)方式尽量让cpu少等待多干事。在HTTP1.1中,虽然大家都共用一条TCP通道,但一个请求没有结束,第二个请求就可能阻塞等待,也就是不能同时发送接收数据,那么一个网页很多数据文件,如果能同时发出请求,让部分数据文件得到响应并预处理,那么就大大利用了带宽和cpu
因此3.0根据TCP的这些缺陷研究了QUIC协议
HTTP协议组成
HTTP协议包括HTTP请求和HTTP响应组成
- HTTP请求包括:请求行,请求头,请求体
- HTTP响应包括:响应行,响应头,响应体
HTTP请求与响应结构
请求报文
GET /article/12 HTTP/1.1
Host: www.xxx.cn
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: SESSION=so9nlsvenminor5abs65sh9dsa
-
请求行:
- 请求方法:GET,POST等HTTP方法,还包括DELETE,PUT,OPTIONS,HEAD,TRACE
- URL:为请求对应的URL地址,它和请求头的Host属性组成完整的URL
- HTTP版本:常用的版本是HTTP/1.1
-
请求头:HTTP的报文头,其中包含若干属性,格式为”属性名:属性值“
常见头部包括:
-
Host:指定要请求的资源所在的主机和端口
-
Connection:连接方式,一般为keep-alive保持长连接
-
Cache-Control:对缓存进行控制,如一个请求希望响应的内容在客户端缓存一年,不被缓存可以通过这个请求头设置, 常见的取值有private、public、no-cache、max-age,no-store,默认为private
-
Accept:告诉服务器客户端接受什么类型的响应,如
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,applicat
-
Accept-Encoding:告诉服务器能接受什么编码格式,包括字符编码,压缩形式(一般都是压缩形式)
-
User-Agent:告诉服务器客户端使用的操作系统、浏览器版本和名称
-
Cookie:客户端的Cookie就是通过这个报文头属性传给服务器的
-
Referer :表示这个请求是从哪个URL过来的
-
-
请求体:即报文主体
响应报文
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 17 May 2020 17:04:29 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: blade-2.0.6-BETA
Content-Encoding: gzip
-
响应行:
- HTTP版本
- 状态码:HTTP的5种状态码
- 状态码描述:不同的状态码代表不同的结果
-
响应头:
常见的响应头包括:
- Server:服务器用来处理请求的系统信息,与User-Agent请求头是对应的
- Content-type:发送给请求者的实体正文媒体类型,如
text/html
- Content-Lengrh:实体正文的长度
- Set-Cookie:服务器通过这个响应头去设置客户端的Cookie
- Content-Encoding:服务器使用的压缩格式,比如gzip,因为一般数据过大就会进行压缩
- Transfer-Encoding: 传输编码,一般是chunked分块编码,在头部加入这个属性后就代表分块编码,主要用于解决长连接中将数据分块传输后如何判断内容传输结束,利用他就能解决长连接中的粘包问题, 分块的格式为数据长度(16进制)+ 分块数据 ,数据长度为0表示结束
-
响应体:响应的数据内容
HTTP主要特点
HTTP即超文本传输协议,具有以下几个特点
- 支持客户端/服务器模式
- 简单快速
- 灵活:允许传输任意类型的对象
- 无连接:每次连接只处理一个请求,请求响应后,连接关闭
- 无状态:对于事务处理没有记忆,即请求结束后不会记住之前的连接状态
HTTP状态码
-
1XX:处于中间状态,还需后续操作
-
2XX:成功收到报文并正确处理
- 200 OK
- 204 No Content :响应头中没有body数据—如HEAD请求?
- 206 Partial Content :body里的数据不是资源的全部,而是其中一部分,并且通常伴随着头字段”Content-Range”,表示数据的范围,供客户端确认—如断点续传
-
3XX:重定向到其他资源服务器
-
301 Moved Permanently :永久重定向,本地请求资源不存在,使用新的URL请求
-
302 Found :临时重定向,请求的资源还在,但目前需要另一个URI访问
(301和302可以在Location中标明需要跳转的URI,举个例子,有时候需要将网站全部升级为HTTPS,则需要配置永久的301,有时候需要更新系统,则配置临时的302)
-
304 NOT Modified :运用于缓存控制,缓存重定向
-
-
4XX:请求报文有误,服务器无法处理
- 400 Bad Request :通用错误码,是一个很笼统的错误
- 401 Unauthorized:请求未经授权,这个状态码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden :表示服务器禁止访问资源
- 404 Not Found :资源在本地未找到,从而无法提供给服务器
- 405 Method Not Allowed :方法错误,比如服务器接口使用POST,而请求视同的是GET,就会出现这个错误
- 406 Not Acceptable :客户端资源无法满足客户端请求的条件,例如请求需要中文但只有英文
- 408 Request Timeout :请求超时,服务器等待了过长时间
- 409 Confilct :多个请求发生的冲突
- 413 Request Entity Too Large :请求报文的请求体body太大
- 414 Request-URI Too Long :请求行里的URI太大
- 429 Too Many Requests :客户端发送了大多请求
- 431 Request Header Fields Too Large :请求头某个字段或总体太大
-
5XX:服务器错误,服务器处理请求时内部发生错误
- 500 Internal Server Error :和400类似,属于服务器的通用错误码,服务器具体什么错误我们不知道,这样也是一件好事,保证尽量少的服务器资源暴露给外面,尽量保证了服务器资源
- 502 Bad Gateway :通常为服务器作为网关或代理时返回的错误,表示服务器自身工作正常,访问后端服务器时网关发生错误,具体什么错误我们不得而知
- 503 Service Unavailable :表示服务器当前很忙,暂时无法响应服务,上网遇到的“服务器正忙,请稍后重试”的提示状态码就是503(503是一个临时的状态,暂时比较忙,稍后提供服务)
一次完整HTTP请求经历的过程
大致过程:
-
输入域名,浏览器发起请求,如https://xxx/xxx/xxx的页面
-
DNS域名解析,找到目标服务器的IP,DNS缓存从近到远依次是浏览器缓存,系统缓存,路由缓存,ips服务器缓存,域名缓存,顶级域名缓存
-
TCP三次握手建立连接
-
客户端的TCP将HTTP请求报文分割成多个报文段,然后按顺序将每个报文段发送给服务器
-
通过IP协议搜索服务器的地址,然后通过ARP协议获取每个中间传输节点MAC地址,进行中转传送
-
数据传送到服务器,服务器的TCP协议将收到的报文段按顺序重组为请求报文
-
服务器的HTTP协议对请求的内容进行处理
-
服务器处理后同样利用TCP/IP通信协议返回应答给客户端
-
四次挥手关闭连接
注意:(一般情况下,一旦 Web 服务器向浏览器发送了请求的数据,它就要关闭 TCP 连接,但是如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。)
HTTP支持的请求方法
HEAD:和Get类似,但是从服务器请求的资源不会返回请求的实体数据,只会返回响应头
Get和Post的区别
- 作用:Get请求是向指定资源请求数据;Post是向指定资源服务器提交数据并处理请求
- 报文层面:Get请求将数据放在url,Post将数据放在请求体中
- 幂等性:在浏览器中,Get一个html文件,反复读取不应该对数据产生影响,是幂等性的,因此可以对Get获取到的数据做缓存(缓存到浏览器,代理ngix,server端);当我们有一个表单form,然后使用post请求发送到服务器,这个会改变服务器数据,是非幂等性的,当然也可以让Get有副作用,Post无副作用,只不过与浏览预期不符,而且使用Get修改数据可能会造成安全漏洞(数据可见)
- 安全性:Get请求的数据被放在url中进行传输,能够被外界看到,而Post请求是将数据放在请求体中传输,外界看不到,因此Post比Get更加安全,但无论是Get还是Post都不够安全,因为HTTP本身是明文传输,不管是url,header还是body,请求和返回的每一个字都是明文,通过抓包就可获取所有信息,为了避免数据被窃取,必须使用如HTTPS的端端加密传输,即在应用层和传输层之间加入TLS协议(包含SSL握手协议,SSL密码规范协议,SSL报警协议,SSL记录协议),
- 数据量:Get传输的数据量少,因为受URL长度的限制(HTTP协议本身没有对URL做任何限制,实际限制的是客户端/浏览器以及服务器决定的,比如Chrome的URL限制为2MB);Post传输的数据量大,一般认为不受限制
- 编码方式:Get参数只支持ASCLL,这是因为URL只支持ASCLL;Post支持任意编码,包括中文;因此确切的说应该区分url和body分别用什么编码
- 有无请求体:GET请求没有请求体。POST请求有请求体。
Post与Put的区别
- PUT 请求:如果两个请求相同,后一个请求会把前面的一个请求覆盖掉。(所以 PUT 用来更新资源)
- POST 请求:后一个请求不会把第一个请求覆盖掉。(所以 POST 用来新增资源)
HTTP粘包处理
对于TCP字节流的数据,需要使用一定的方式去获取数据包,在HTTP数据中包含请求头,请求头的某些属性可以进行处理
-
Content-Lengrh:如果事先知道返回的数据大小,并且数据不大,那么可以在请求头中加入Content-Length数据长度字段来指示读取多少个字节算这个包结束,这就避免了
粘包
问题 -
Transfer-Encoding:如果文件大小事先不知道或者还在动态增长,那么可以使用分块传输,在响应头中加入
Transfer-Encoding:chunked
表示分块传输
如何做断点续传
HTTP1.1 协议开始支持获取文件的部分内容,这为并行下载以及断点续传提供了技术支持。它通过在 Header 里两个参数实现的,客户端发请求时对应的是 Range
,服务器端响应时对应的是 Content-Range。
Range:用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式为:
Range:(unit=first byte pos)-[last byte pos]
Range可能出现的情况:
Range: bytes=0-499 表示第 0-499 字节范围的内容
Range: bytes=500-999 表示第 500-999 字节范围的内容
Range: bytes=-500 表示最后 500 字节的内容
Range: bytes=500- 表示从第 500 字节开始到文件结束部分的内容
Range: bytes=0-0,-1 表示第一个和最后一个字节
Range: bytes=500-600,601-999 同时指定几个范围
Content-Range :用于响应头中,在发出Range请求后,服务器会在Content-Range头部返回当前接收的范围和文件总大小,一般格式为:
Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]
例如 Content-Range: bytes 0-499/22400
根据上述两个请求头就可以描述断点续传:比如我现在要从服务器下载一个名为test.zip的文件,那么请求内容可以为
GET /test.zip HTTP/1.1
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
服务器收到后按要求寻找请求的文件,提取文件信息,然后返回如下
HTTP/1.1 200 OK
Content-Length=66667777
Accept-Ranges=bytes
Content-Type=application/octet-stream
为了实现从已经下载的地方继续下载,那么客户端向服务器请求时就需要多加上上面所说的Range请求头,比如
GET /test.zip HTTP/1.1
User-Agent: NetFox
RANGE: bytes=44445555-
那么服务器收到就会从44445555这个字节开始传,前面的字节就不传了,服务器返回
HTTP/1.1 206 Partial Content
Content-Length=66667777
Content-Range=bytes 44445555-66667777
Content-Type=application/octet-stream
这样就实现了断点续传,其中状态码由200变为了206,表示服务器已经处理了部分请求
Cookie和Session
为什么需要Cookie和Session
无状态的HTTP协议
由于http协议是无状态的协议(也就是每次断开连接后都是一次新的连接请求,服务器不能根据你打开的链接恢复上一次的会话,即不认识你是谁),为了能够记住请求的状态,于是引入了Session和Cookie的机制,将之前的信息记录在cookie中,下次请求建立连接后,将cookie信息发给服务器,服务器就能解析cookie信息识别身份了, 为你提供专门属于你的内容
比如我们从网站的登陆界面中看到有记住我
这个选项,你勾选了它以后,登陆成功,浏览器就会把你的信息放在cookie里,下次再访问这个网站的时候,服务器就能根据收到的cookie识别出是你,帮你自动登陆,显示专属于你的内容。
会话(Session)跟踪
会话,指用户访问网站的一个周期,比如浏览商品添加到购物车并购买。会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
区别:
- Cookie数据存放在客户的浏览器上,Session数据放在服务器上
- Session相对于Cookie安全,Cookie可以查看
- Session会在一定时间内保存在服务器上,当访问增多,比较占用性能,若考虑减轻服务器负担,应使用Cookie
cookie
- 由服务器发送给客户端的特殊信息,以文本的形式存放在客户端
- 客户端再次请求的时候,会将Cookie回发(在请求头中,比如在前端存放token,登录之后,服务器将token发送给客户端,客户端保存在cookie中,下次进行其他请求的时候,就可以将Cookie中的token在请求头中带上,发送给服务器)
- 服务器接收到后,会解析Cookie生成与客户端相对应的内容
cookie存储的数量和字符数量都有限制,只能存储几十个,不超4096左右个字符。 cookie的安全性不高,所有人都能看见
session
session在计算机网络应用中被称为“会话控制”。
- 服务器端的机制,在服务器上保存的信息
- 解析客户端请求并操作session id,按需保存状态信息
session的实现方式
- 配合Cookie实现
- 使用URL回写实现(在URL中携带session_id的参数)
配合Cookie实现
客户端浏览器访问网站的时候,服务器会向客户浏览器发送一个每个用户特有的会话编号sessionID,让他进入到cookie里。
服务器同时也把sessionID和对应的用户信息、用户操作记录在服务器上,这些记录就是session。
客户端浏览器再次访问时,会发送cookie给服务器,其中就包含sessionID。
服务器从cookie里找到sessionID,再根据sessionID找到以前记录的用户信息就可以知道他之前操控些、访问过哪里。
session保存在服务器端比较安全,但是可能需要记录千百万用户的信息,对服务器的存储压力很大,所以我们应该有选择的合理使用cookie和session。
Cookei和Session的区别
- 存储位置不同,cookie是保存在客户端的数据;session的数据存放在服务器上
- 存储容量不同,单个cookie保存的数据小,一个站点最多保存20个Cookie;对于session来说并没有上限
- 存储方式不同,cookie中只能保管ASCII字符串;session中能够存储任何类型的数据
- 隐私策略不同,cookie对客户端是可见的;session存储在服务器上,对客户端是透明的
- 有效期上不同,cookie可以长期有效存在;session依赖于名为JSESSIONID的cookie,过期时间默认为-1,只需关闭窗口该session就会失效
- 跨域支持上不同,cookie支持跨域名访问;session不支持跨域名访问
- 典型应用:Cookie,3个月不用再登录;Session,用户登录
应用场景
登录网站,今输入用户名密码登录了,第二天再打开很多情况下就直接打开了。这个时候用到的一个机制就是cookie。
HTTPS
HTTP的传输是不安全的,HTTP在网路上传输都是明文的,容易被第三方截获,要做到安全传输数据,就要对传输数据加密,将HTTP改为HTTPS协议
HTTPS是什么
HTTPS是由SSL/TLS+HTTP协议构建的有加密传输、身份认证的网络协议,他与HTTPS的区别主要在于他在TCP和HTTP协议之间加了一层用于保证数据安全的SSL/TLS协议
SSL/TLS是什么
SSL(Security Sockets Layer)即安全套接字层,他是基于HTTPS下的一个协议加密层,通过数据加密和身份认证来保证数据传输的安全和数据的完整性。SSL3.0以后更名为TLS(Transport Layer Security)
TLS由SSL握手协议,SSL修改密码规范协议,SSL警报协议,SSL记录协议组成
- SSL握手协议:相对于三次握手
- SSL密码变更协议:告诉对方,后续的数据将使用加密算法进行加密再传输
- SSL警报协议:类似HTTP状态码,通过反馈不同的消息进行不同的策略。
- SSL记录协议:记录TLS发送接收数据的基本单位
常见加密方式
- 对称加密:
加密解密效率较高
,安全性较低,加密长度限制小
- DES( Data Encryption Standard ): 数据加密标准 , 加密强度不够,能够暴力破解
- 3DES : 原理和DES几乎是一样的,只是使用3个密钥,对相同的数据执行三次加密,增强加密强度。 ( 维护3个密钥,大大增加了维护成本 )
- AES( Advanced Encryption Standard ): 高级加密标准,目前美国国家安全局使用的
- 非对称加密:算法强度复杂,
加密解密效率较低
,安全性较高,加密长度有限
- 哈希Hash:将不同长度的数据通过哈希算法压缩成一样的长度,运算不可逆
- MD5
实际使用中由于非对称加密的加密长度限制,加密效率等问题,我们通常使用对称加密去加密文件,然后使用非对称加密加密对称加密的秘钥
HTTPS的数据传输流程
- 浏览器先发送一次握手信息给服务器,将支持的加密算法信息发送给服务器
- 服务器选择一套浏览器支持的加密算法,以证书(包括证书的发布机构CA,证书的有效期,公钥,证书所有者,签名)的形式回发给浏览器
- 浏览器验证证书合法性,如果证书合法,则随机生成一对秘钥,并结合证书公钥加密信息发送给服务器
- 服务器使用私钥解密信息,验证哈希,使用浏览器的公钥加密响应消息回发浏览器
- 浏览器解密响应消息,并对消息进行验真,之后进行加密交互数据
HTTP与HTTPS的区别
因此HTTP与HTTPS的区别如下:
-
HTTPS比HTTP多了一套SSL安全数据传输协议,该SSL协议位于应用层和传输层之间
HTTPS=HTTP+加密+认证(数字签名)+完整性保护(摘要)
-
HTTPS需要去CA申请证书
-
HTTPS是密文传输,HTTP明文传输
-
连接方式不同,HTTPS默认使用443端口,HTTP默认使用80端口
其他协议
ARP协议
ARP( Address Resolution Protocol )即地址解析协议, 其作用是在以太网环境中,数据的传输所依懒的是MAC地址而非IP地址,而将已知IP地址转换为MAC地址的工作是由ARP协议来完成的。 、
ARP工作原理
每台主机会在自己的ARP缓冲区建立一个ARP列表,表示IP和MAC地址的映射关系,当源主机需要将一个数据报发送给目的主机时,需要检查自己的ARP列表中是否存在该IP和MAC地址的映射,如果有,则直接将数据发送到这个MAC地址,如果没有则向本地网段
发送一个ARP请求的广播包,查询此目的主机对应的MAC地址,此请求包包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致,如果不同则忽略该数据包,如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP列表已经存在IP信息,则将其覆盖,然后给源主机发送一个ARP响应包,告诉对方它需要查询的MAC地址; 源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
广播发送ARP请求,单播发送ARP响应。 就像A需要知道某IP的MAC地址,那么他就在本网段广播大喊,谁是某IP这个主机,把你的MAC地址告诉我,然后该IP的主机接收到这个信息后就私聊A,告诉他MAC地址
ICMP协议
ICMP(Internet Control Message Protocol)即因特网控制报文协议,它属于网络层协议,是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等
从技术角度来说,ICMP就是一个“错误侦测与回报机制”
,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性。当路由器在处理一个数据包的过程中发生了意外,可以通过ICMP向数据包的源端报告有关事件。
ping和tracert就是利用ICMP来实现的网络功能
DNS协议
DNS(Domain Name System)即域名系统,它用来将域名转换为IP地址(也可以将IP地址转换为相应的域名地址)。DNS使用TCP和UDP端口53。他其实就是一个将域名和IP地址相互映射的一个分布式数据库,DNS缓存从近到远依次是浏览器缓存,系统缓存,路由缓存,ips服务器缓存,域名缓存,顶级域名缓存
为什么不用域名直接进行通信?
-
因为IP地址是固定长度的,IPv4是32位,IPv6是128位,而域名是变长的,不便于计算机处理。
-
IP地址对于用户来说不方便记忆,但域名便于用户使用,例如www.baidu.com这是百度的域名。
总结一点就是IP地址是面向主机的,而域名则是面向用户的。
域名和IP的对应关系保存在一个叫hosts文件中 但是如果某个计算IP变更都需要到信息中心申请变更hosts文件。其他计算机也需要定期更新,才能上网,这样太麻烦了,就出现了DNS系统。
什么是域名
先说说URL
URL( Uniform Resource Locator )即统一资源定位符, 它是WWW的统一资源定位标志,就是指网络地址,它由4部分组成:协议、主机、端口、路径 ,他也是一种URI( Uniform Resource Locator )统一资源定位符
URL的一般语法格式为(带方括号[]的为可选项):
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
什么是域名
域名本质是一个名字空间系统
,采用多级域名的方式区分不同的国家,公司等,作为一种身份的标识。域名按照”.”分割组成互联网上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的方位 ,越靠近右边级别越高
域名构成: 域名由两个或两个以上的词构成, 中间由点号分隔开。最右边的那个词称为顶级域名。
- 根域:DNS域名使用中规定由尾部句点\’.\’来指定名称位于根或者更高层次的域层次结构,根服务器有13台。
- 顶级域名:比如.com用于商业机构,.NET最初用于网络组织,.TOP用于行业内顶级企业或个人,国家代码由两个字母组成顶级域名如.cn,.uk
- 二级域名:顶级域名的下一级就是二级域名
www.baidu.com是域名吗
是域名,但严格意义上,只有baidu.com
算域名,而www是主机名(比如www代表网页,blog代表博客),而baidu.com是二级域名,从后向前,.com是顶级域名,然后往前是二级三级.baidu.com是二级域名,www是主机名
,是服务器识别你是要访问啥的一个标识,可以自己随便取名字,看你的服务器怎么设置了,可以配置下nignx或者阿帕奇,看看conf文件是咋配置域名的,你可以配置*.baidu.com也可以www.baidu.com
域名服务器
域名是分层结构,域名服5务器也是对应的层级结构,域名服务器其实就是有域名系统的主机
由高向低进行层次划分,可分为以下几类:
分类 | 作用 |
---|---|
根域名服务器 | 最高层次的域名服务器,本地域名服务器解析不了的域名就发送给他 |
顶级域名服务器 | 负责管理在该顶级域名服务器下注册的二级域名,全球13台服务器 |
权限域名服务器 | 负责一个区的域名解析工作 |
本地域名服务器 | 当一个主机发出DNS查询请求时,这个查询请求首先发送给本地域名服务器 |
域名解析
通过域名去查询域名服务器得到IP地址的过程称为域名解析。
域名到IP地址的映射有两种方式:
- 静态映射:在本机上配置域名和IP的映射,只在本机使用,Windows和Linux的hosts文件中的内容就属于静态映射
- 动态映射:建立一套域名系统(DNS),只在专门的DNS服务器上配置主机到IP地址的映射,网络上需要使用域名通信的设备,首先到DNS服务器查询主机所对应的IP地址
在域名解析时,一般先静态域解析,再动态解析域名,可以将常用的域名放入静态域名解析表中,这样可以大大提高域名解析效率。
具体解析过程为
- 在浏览器中输入www.qq.com域名,客户端首先查看浏览器缓存里面是否有该映射缓存,如果有则使用,如果没有则访问本机系统缓存,如果没有操作系统就去检查本地的hosts文件查看是否有这个网址映射关系,如果有,就调用这个IP地址映射,完成域名解析
- 如果DNS缓存和hosts文件里都没有域名的映射,那么就查看TCP/IP参数中设置的首选DNS服务器,它成为本地DNS服务器,此服务器收到查询后,判断查询的域名是否在本地配置区域资源中,如果在,则返回给客户机完成解析。
- 如果查询的域名不在本地DNS服务器区域解析,那么将请求发至根域名服务器,根域名服务器收到后判断顶级域名(.com)由谁授权管理,然后将这个负责该顶级域名管理的服务器IP返回,本地DNS服务器收到IP信息后,将查询信息发送给这台顶级域名管理的服务器,如果该服务器无法解析,就将管理.com域的下一级DNS服务器(qq.com)的IP给本地服务器,本地服务器收到这个服务器IP后再去这个qq.com服务器查询,知道最后找到www.qq.com主机的IP
递归查询:从本地服务器到权限域名服务器,再从权限域名服务器返回本地服务器再到本机,这就是递归
迭代查询:相当于循环依次查找,本地服务器先查根域名服务器,再查顶级域名服务器,再查权限域名服务器,这就是迭代查询
递归是自己调用自己一层层进入,每次旨在缩小问题规模。迭代是自己执行很多次,每次旨在更接近目标。
DNS劫持
一个形象的比喻就是,dns就是指路的,而挟持就是被坏人要挟,瞎指路。本来你要访问这个域名的IP是A,他给你返回一个B,让你去访问B的网页,这就是被劫持了。
DNS挟持就是把目标网站域名解析到错误的IP地址从而实现用户无法访问目标网站的目的或者蓄意或恶意要求用户访问指定IP地址(网站)的目的。
DNS使用的传输协议
DNS在区域传输的时候使用TCP协议,其他时候使用UDP协议。
为什么既使用TCP又使用UDP: UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。当DNS查询超过512字节时,协议的TC标志出现删除标志,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。
区域传送时使用TCP : 辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。
域名解析时使用UDP: 客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。
Socket
Socket是应用层与传输层之间的中间软件抽象层,它是一组编程接口(API)。它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。
Socket数据传输过程:
实现Socket传输数据
比如通过TCP和UDP两种方式实现通信,客户端向服务器发送一个字符串,服务器收到该字符串后将其打印到命令行,然后向客户端返回该字符串的长度,最后客户端输出服务器返回的该字符串长度。
TCP部分
Server
package com.esperdemo;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @program: demo
* @description:
* @author: sirelly
* @create: 2020-09-13 15:40
**/
public class TCPServer {
public static void main(String[] args) throws IOException {
//创建socket,并将socket绑定到9003端口
ServerSocket serverSocket = new ServerSocket(9003);
//循环监听,使socket一直等待并处理客户端发送过来的请求
while (true){
//监听9003端口,知道客户端返回连接信息后才返回
Socket socket = serverSocket.accept();
//获取信息后执行业务流程
new LengthCalculator(socket).start();
}
}
}
package com.esperdemo;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* @program: demo
* @description:
* @author: sirelly
* @create: 2020-09-13 15:45
**/
public class LengthCalculator extends Thread {
private Socket socket;
public LengthCalculator(Socket socket){
this.socket = socket;
}
@Override
public void run(){
try{
//获取Socket的输出流
OutputStream os = socket.getOutputStream();
//获取Socket的输入流
InputStream is = socket.getInputStream();
//用来获取读取数组的长度
int ch = 0;
//将读取到的数据存入buff中
byte[] buff = new byte[1024];
ch = is.read(buff);
//将接受到的byte数组转换为字符串
String s = new String(buff, 0, ch);
System.out.println(s);
//往输出流里写入获得字符串的长度,回发给客户端
os.write(String.valueOf(s.length()).getBytes());
is.close();
os.close();
socket.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
Client
package com.esperdemo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* @program: demo
* @description:
* @author: sirelly
* @create: 2020-09-13 19:23
**/
public class TCPClient {
public static void main(String[] args) throws IOException {
//创建socket,并制定连接服务器的IP和端口
Socket socket = new Socket("127.0.0.1", 9003);
//获取输出流
InputStream is = socket.getInputStream();
//获取输入流
OutputStream os = socket.getOutputStream();
//将需要传递给server的字符串参数转换为byte数组,并将数组写入输出流
os.write(new String("hello world").getBytes());
int ch = 0;
byte[] buff = new byte[1024];
//buff用来获取输入内容,存入byte数组中,ch用来获取数组的长度
ch = is.read(buff);
String content = new String(buff, 0, ch);
System.out.println(content);
is.close();
os.close();
socket.close();
}
}
常见网络设备
比如交换机、路由器、网关等常用网络设备
交换机
- 交换机可以将一个网络端口分成多个网络端口,然后将连接交换机的机器连接起来组成一个局域网,对外的IP地址不同
- 交换机工作于OSI参考模型的第二层,即数据链路层 ,根据MAAC地址寻址。
交换机的工作原理
比如现在有交换机A和交换机B,交换机A有主机1和主机2,交换机B有主机3和主机4,交换机A的端口3连接交换机B的端口3,现在主机1需要发送信息到主机3,那么会经历以下几步:
- 主机1发送消息到交换机A,交换机A收到数据后识别主机的MAC地址和端口号(假设交换机A和B的地址表都是空白 )
- 交换机A查找自己的MAC地址表,发现没有要发送的MAC地址,交换机A就向其他所有端口广播
- 交换机B收到数据后就识别并学习源地址和过来的端口号
- 交换机B查看地址表,发现没有地址,则记录并向除了端口3的其他端口发送广播包
- 主机2收到数据后对比不是自己的,则丢弃数据,而主机3收到后发现是自己则接受数据
路由器
- 路由器用于
连接不同网段
并找到网络中数据传输最合适的路径 - 路由器主要克服了交换机不能路由转发数据包的不足
- 路由器在网络层,根据IP地址寻址
路由器工作原理:
比如主机A要发送数据到主机B,而主机A和主机B不在一个网段下
- 主机A发送数据给主机B,A将B的IP地址和数据一起发送给路由器R1
- 路由器R1收到数据包后先将数据中读取B的IP地址,然后根据路径表计算发往B的最优路径
- 比如路径为:R1->R2->R5->B;并将数据包发往路由器R2。
- 路由器2重复路由器1的工作,并将数据包转发给路由器5。
- 路由器5同样取出目的地址,发现目的地址就在自己的网段上,于是将该数据包直接交给主机B。
计网的知识真的太多太多,这里只是小小的总结了几点,看的越多,不会的越多,还需继续攀登....
参考: https://blog.csdn.net/qq_42651904/article/details/91355804
https://www.cnblogs.com/qiaozhoulin/p/5075372.html
https://www.cnblogs.com/hbkzhu/p/9692153.html
https://blog.csdn.net/qq_41431406/article/details/97926927
https://www.zhihu.com/question/34074946
https://blog.csdn.net/baidu_37964071/article/details/80500825
https://blog.csdn.net/wytheonly/article/details/37925067
https://www.cnblogs.com/adongyo/p/11617427.html
一文领略 HTTP 的前世今生
https://blog.csdn.net/weixin_33832340/article/details/90529737?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control