计算机网络总结#
一、体系结构#
应用层
:应用层协议定义的是应用进程间通信和交互的规则,为特定应用程序提供数据传输服务,例如 HTTP、DNS 等。数据单位为报文运输层
:运输层的任务就是负责向两台主机中进程之间的通信提供通用的数据传输服务 (TCP 或 UDP)网络层
:把运输层产生的报文段或用户数据报封装成分组或包进行传送数据链路层
:将网络层交下来的 IP 数据报组装成帧,并在两个相邻结点间的链路上传送物理层
:利用物理媒体以比特形式传送数据
物理层信道复用技术#
基本概念#
信道,向某一个方向传送信息的媒体,包括
- 单向信道:一方发送,一方接收,
单工
- 双向交替信道:双方都可发送消息,但不能同时进行,
半双工
- 双向同时信道:双方可同时发送信息,
全双工
复用,即信道共享,几种常见的信道复用技术:频分复用,时分复用,统计时分复用。通过复用器和分用器进行信号的复用和分用
信道复用技术#
1. 频分复用 FDM
用户在同样的时间内占用不同的频率带宽而复用同一个信道
2. 时分复用 TDM
将时间划分为相同的时分复用帧 TDM,在不同的时间占用相同的频带宽度,
**3. 统计时分复用 STDM **
改进的时分复用,按需动态分配时隙,而不是固定分配时隙 (时隙数小于连接在集中器上的用户数,使得每次传送的 STDM 帧中的分组都是满的
4. 波分复用 WDM
光的频分复用,利用在光线技术通信中;
5. 码分复用 CDM
每个用户在相同的时间使用相同的频带进行通信,但各用户使用经过挑选的不同码型,从而使得个用户之间可以进行独立的通信
数据链路层#
数据链路层的主要功能:
- 链路管理
- 帧同步
- 流量控制
- 差错控制
- 将数据与控制信息区分开
- 透明传输
- 寻址
数据链路层的三个基本问题:封装成帧
,透明传输
,差错检测
封装成帧#
将 IP 数据报的前后分别添加首部和尾部构成帧,以便于接收端能够在物理层的比特流中知道帧的开始和结束,即进行帧定界;
此外,首部和尾部还要添加许多控制信息,链路层协议规定了所能传送的帧的数据部分长度上限,最大传送单元 ——MTU
透明传输#
透明传输的概念是指在数据链路层传输时,所传输的数据在数据链路层没有任何的阻挡,接收方所收到的数据和发送方发送的数据没有任何差别,也就是说,数据链路层对其传输的数据帧是完全透明的;
字节填充:
在传输的过程中,为防止数据部分出现帧定界符,使得接收方误以为收到的数据提前结束,所以采用转义字符的方法,将在数据部分出现的控制字符前插入转义字符,,在接收方的数据链路层将插入的转义字符删除
零比特填充法:
只要发现 5 个连续 1,则立即填入一个 0,保证不出现 6 个连续 1
差错检测#
差错检测指的是在传输过程中产生的比特差错;
** 误码率:** 一段时间内,传输错误的比特占传输总数的比率;
目前在数据链路层采用的差错检验方式是循环冗余检验;
注:
在数据链路层我们保证的是无比特差错,而并无传输差错,传输差错还包含帧丢失
,帧重复
,帧失序
等;
二、IP 地址#
概述#
计算机要实现网络通信,就必须要有一个用于快速定位的网络地址。IP 地址就是计算机在网络中的唯一身份 ID,与现实世界中快递的配送需要有具体的住宅地址是一个道理。
IP 地址 = 网络地址 + 主机地址 (又称:主机号和网络号组成)
网段划分#
A 类地址:以 0 开头,第一个字节范围:0 - 127(1.0.0.0 - 126.255.255.255
);
B 类地址:以 10 开头, 第一个字节范围:128 - 191(128.0.0.0 - 191.255.255.255
);
C 类地址:以 110 开头, 第一个字节范围:192 - 223(192.0.0.0 - 223.255.255.255
);
Internet 上保留地址用于内部私有使用: 10.0.0.0 - 10.255.255.255
, 172.16.0.0 - 172.31.255.255
, 192.168.0.0 - 192.168.255.255
。
子网掩码#
-
在划分子网的时候,我们将本来属于主机号的一部分划分到网络号中,为了便于区分哪部分是网络号,哪部分是主机号,这就需要通过子网掩码来实现
-
子网掩码不能单独存在,它必须结合 IP 地址一起使用。
-
子网掩码只有一个作用,就是将某个 IP 地址划分成网络地址和主机地址两部分。
子网掩码的计算#
利用子网数来计算子网掩码#
计算规则:
-
将子网数目转化为二进制来表示
-
取得该二进制的位数,为 N
-
取得该 IP 地址的类子网掩码,将其主机地址部分的前 N 位置 1 即得出该 IP 地址划分子网的子网掩码
如欲将 B 类 IP 地址 168.195.0.0 划分成 27 个子网:
1)27=11011
2) 该二进制为五位数,N = 5
3) 将 B 类地址的子网掩码 255.255.0.0 的主机地址前 5 位置 1,得到 255.255.248.0 即为划分成 27 个子网的 B 类 IP 地址 168.195.0.0 的子网掩码
利用主机数来计算子网掩码#
计算规则:
-
将主机数目转化为二进制来表示
-
如果主机数小于或等于 254(注意去掉保留的两个 IP 地址),则取得该主机的二进制位数,为 N,这里肯定 N<8。如果大于 254,则 N>8,这就是说主机地址将占据不止 8 位。
-
使用 255.255.255.255 来将该类 IP 地址的主机地址位数全部置 1,然后从后向前的将 N 位全部置为 0,即为子网掩码值
如欲将 B 类 IP 地址 168.195.0.0 划分成若干子网,每个子网内有主机 700 台:
- 700=1010111100
2) 该二进制为十位数,N = 10
3) 将该 B 类地址的子网掩码 255.255.0.0 的主机地址全部置 1,得到 255.255.255.255 然后再从后向前将后 10 位置 0, 即为: 11111111.11111111.11111100.00000000 即 255.255.252.0。这就是该欲划分成主机为 700 台的 B 类 IP 地址 168.195.0.0 的子网掩码
三、UDP#
概述#
- 用户数据报协议 UDP 只在 IP 的数据报服务至上增加了复用和分用的功能以及差错检测的功能。只有
面向无连接的报文
,不可靠传输
的特点。 - UDP 对应用层交下来的数据只添加首部,并进行特别的处理,就交给网络层;
- 对网络层传递上来的用户数据报拆封首部后,原封不动的交给应用层
UDP 首部格式#
UDP 首部字段很简单,由 4 个字段组成,每个字段的长度都是两个字节,共 8 字节。
- 源端口号:在需要对方回信时选用,不需要时可全 0
- 目的端口号:这在终点交付报文时必须使用,不然数据交给谁呢?
- 长度: UDP 的长度,最小值为 8 字节,仅有首部
- 检验和: 检测用户数据报在传输过程是否有错,有错就丢弃。
在传输的过程中,如果接收方 UDP 发现收到的报文中的目的端口不存在,会直接丢弃,然后由网际控制报文协议 ICMP 给发送方发送 “端口不可达” 差错报文
关于循环冗余校验法,详见: CRC(循环冗余校验码)简介与实现解析
四、TCP#
TCP 协议作为传输层主要协议之一,是面向连接,端到端,可靠的全双工通信,面向字节流的数据传输协议
TCP 报文段#
虽然 TCP 面向字节流,但 TCP 传输的数据单元却是报文段。TCP 报文段分为TCP首部
和数据部分
,TCP 报文段首部的前20个字节
是固定的,后面有 4n 字节根据需要动态添加的选项,最大长度为 40 字节
-
源端口和目的端口
各占两个字节,TCP 的分用功能也是通过端口实现的。 -
序号(Sequence Number)
占 4 个字节,范围是 [0,232],TCP 是面向字节流的,每个字节都是按顺序编号。例如一个报文段,序号字段是 201,携带数据长度是 100,那么第一个数据的序号就是 201,最后一个就是 300。当达到最大范围,又从 0 开始。 -
确认
号 占 4 个字节,是期望收到对方下一个报文段的第一个字节的序号。若确认号 = N, 则表示序号 N 前所有的数据已经正确收到了。 -
数据偏移
占 4 位,表示报文段的数据部分的起始位置,距离整个报文段的起始位置的距离。间接的指出首部的长度。 -
保留
占 6 位,保留使用,目前为 0. -
URG(紧急
) 当 URG=1, 表明紧急指针字段有效,该报文段有紧急数据,应尽快发送。 -
确认号(Acknowledgement Number)
仅当 ACK=1 时,确认号才有效,连接建立后,所有的报文段 ACK 都为 1。 -
PSH(推送)
接收方接收到 PSH=1 的报文段,会尽快交付接收应用经常,不再等待整个缓存填满再交付。实际较少使用。 -
RST(复位)
RST=1 时,表明 TCP 连接中出现严重差错,必须是否连接,再重连。 -
SYN(同步)
在建立连接时用来同步序号。当 SYN=1,ACK=0,则表明是一个连接请求报文段。SYN=1,ACK=1 则表示对方同意连接。TCP 建立连接用到。 -
FIN(终止)
用来释放一个连接窗口。当 FIN=1 时,表明此报文段的发送方不再发送数据,请求释放单向连接。TCP 断开连接用到。 -
窗口
占 2 个字节,表示发送方自己的接收窗口,窗口值用来告诉对方允许发送的数据量。 -
校验和
占 2 字节,检验和字段查验范围包括首部和数据部分。 -
紧急指针
占 2 字节,URG=1 时,紧急指针指出本报文段中的紧急数据的字节数(紧急字节数结束后为普通字节)。 -
选项
长度可变,最长可达 40 字节。例如最大报文段长度 MSS。MSS 指的是数据部分的长度而不是整个 TCP 报文段长度,MSS 默认为 536 字节长。窗口扩大,时间戳选项等
三次握手#
-
第一次:客户端发送连接请求报文给服务端,其中 SYN=1,seq=x (代表客户端的初始序列号),即
ISN(Initial Sequence Number, 初始序号)
。发送完毕后进入 SYN_END 状态。 -
第二次:服务端接收到报文后,发回确认报文,其中 ACK=1,ack=x+1,因为需要客户端确认,所以报文中也有 SYN=1,seq=y 的信息。发送完后进入 SYN_RCVD 状态。
-
第三次: 客户端接收到报文后,发送确认报文,其中 ACK=1,ack=y+1。发送完客户端进入 ESTABLISHED 状态,服务端接收到报文后,进入 ESTABLISHED 状态。到此,连接建立完成
三次握手原因
避免资源被浪费掉。如果在第二步握手时,由于网络延迟导致确认包不能及时到达客户端,那么客户端会认为第一次握手失败,再次发送连接请求,服务端收到后再次发送确认包。在这种情况下,服务端已经创建了两次连接,等待两个客户端发送数据,而实际却只有一个客户端发送数据,就会造成资源浪费
四次挥手#
四次挥手指客户端和服务端各发送一次请求终止连接的报文,同时双方响应彼此的请求
-
第一次挥手:客户端发送 FIN=1,seq=x 的包给服务端,表示自己没有数据要进行传输,单面连接传输要关闭。发送完后,客户端进入 FIN_WAIT_1 状态。
-
第二次挥手:服务端收到请求包后,发回 ACK=1,ack=x+1 的确认包,表示确认断开连接。服务端进入 CLOSE_WAIT 状态。客户端收到该包后,进入 FIN_WAIT_2 状态。此时客户端到服务端的数据连接已断开。
-
第三次挥手:服务端发送 FIN=1,seq=y 的包给客户端,表示自己没有数据要给客户端了。发送完后进入 LAST_ACK 状态,等待客户端的确认包。
-
第四次挥手:客户端收到请求包后,发送 ACK=1,ack=y+1 的确认包给服务端,并进入 TIME_WAIT 状态,有可能要重传确认包。服务端收到确认包后,进入 CLOSED 状态,服务端到客户端的连接已断开。客户端等到一段时间后也会进入 CLOSED 状态。
注:
- 默认情况下 (不改变 socket 选项),当你调用 close ( or closesocket,以下说 close 不再重复) 时,如果发送缓冲中还有数据,TCP 会继续把数据发送完。
- 发送了 FIN 只是表示这端不能继续发送数据 (应用层不能再调用 send 发送),但是还可以接收数据
四次挥手原因
由于 TCP 的连接是全双工,双方都可以主动传输数据,一方的断开需要告知对方,让对方可以进行后续相关操作,负责任的表现。
基于 TCP 传输的协议有:FTP(文件传输协议)
、Telnet(远程登录协议)
、SMTP(简单邮件传输协议)
、POP3(和SMTP相对,用于接收邮件)
、HTTP协议
等
“三次握手,四次挥手” 补充#
ISN#
三次握手的一个重要功能是客户端和服务端交换 ISN, 以便让对方知道接下来接收数据的时候如何按序列号组装数据。
如果 ISN 是固定的,攻击者很容易猜出后续的确认号
ISN = M + F(localhost, localport, remotehost, remoteport)
M 是一个计时器,每隔 4 毫秒加 1。 F 是一个 Hash 算法,根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。要保证 hash 算法不能被外部轻易推算得出
TIME_WAIT 状态详解#
TIME_WAIT 状态设置为2 * Maximum Segment Lifetime(报文最大生存时间)
, 存在 TIME_WAIT 状态的原因:
-
LAST_ACK 状态下的 SOCKET 可能会因为超时未收到 ACK 报文而重发 FIN 报文,所以这个 TIME_WAIT 状态的作用就是用来重发可能丢失的 ACK 报文
-
确保连接断开,假如要关闭的这个链接后面在相同的 IP 地址和端口去建立一个新连接,可能会被误认为是旧连接的新请求 (一个 tcp Session 由【源 IP、源端口、目的 IP、目的端口】四元组唯一决定),由于 TCP 报文段最大生存时间为 MSL, 其保持 2MSL 时间可以确保网络上两个传输方向的尚未接收到的、迟到的报文段都已经消失,或被路由器丢弃,而 2MSL 时间后建立新的连接其绝不会收到原来连接的应用程序数据。这样通过设置一个 2MSL 时长的 TIME_WAIT 状态可以让新的连接其绝不会收到原来连接的应用程序数据
序列号回绕#
因为 ISN 是随机的,所以序列号容易就会超过 2^31-1. 而 tcp 对于丢包和乱序等问题的判断都是依赖于序列号大小比较的,此时就出现了所谓的 tcp 序列号回绕(sequence wraparound)问题
半连接和全连接#
半连接队列:
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列
全连接队列:
已经完成三次握手,建立起连接的就会放在全连接队列中,如果队列满了就有可能会出现丢包现象
其他例如syn flood攻击
、Syn Cache技术
、Syn Cookie技术
、SYN Proxy防火墙
等详细请参考:“三次握手,四次挥手” 你真的懂吗?
TCP 可靠传输#
可靠的传输应该满足:
-
传输的信道不产生差错;
-
保证传输数据的正确性,无差错、不丢失、不重复、并且按序到达
TCP 可靠传输的实现:
-
采用三次握手来建立 TCP 连接,四次握手来释放 TCP 连接,从而保证建立的传输信道是可靠的。
-
TCP 采用了
ARQ协议
来保证数据传输的正确性 -
TCP 使用
滑动窗口协议
来保证接方能够及时处理所接收到的数据,进行流量控制。 -
TCP 使用
慢开始
、拥塞避免
、快重传
和快恢复
来进行拥塞控制
,避免网络拥塞
滑动窗口协议#
滑动窗户协议是指数据发送方有一个发送窗口,发送窗口范围内的数据允许发送,随着接收方传来的确认信息以及通知的接收窗口的大小来动态调整发送窗口的起始位置以及大小
窗口的滑动有三种情况:
- 前沿向右移动,这种情况发生在数据发送并被确认时。
- 后沿向右移动,允许发送更多数据。这种情况发生在接收窗口增大或者网络拥塞情况缓解时。
- 后沿向左移动,这种情况发生在接收方希望发送窗口缩小时,TCP 标准强烈不建议出现这种情况。因为发送方在收到缩小窗口的通知时,可能已经发送了一些缩小部分的数据,容易造成错误
- 窗口前沿无法向左移动,因为 TCP 会将窗口之外已经收到确认的数据清除出缓存
ARQ 协议#
ARQ 自动重传请求(Automatic Repeat-reQuest)是一种在数据传输时,使用确认
(Acknoledgements,就是我们常说的ACK
,接收方发送一个消息,告诉发送方,自己是否正确接到了一个包体)和超时
(Timeouts,在收到一个确认消息之前,等待的一个确定的时间段)机制,在不可靠的网络上,实现可靠的数据传输的错误控制方法策略,包括停止等待ARQ协议
和连续ARQ协议
,错误侦测(Error Detection)
、正面确认(Positive Acknowledgment)
、逾时重传(Retransmission after Timeout)
与负面确认继以重传(Negative Acknowledgment and Retransmission)
等机制
停止等待 ARQ:
“停止等待” 是指每发送完一个分组就停止发送,等待对方确认,在收到对方确认后再发送下一个分组,有两种错误情况
- 当接收方收到错误数据分组时,会直接丢弃分组。
- 发送方在一定时间没有收到确认,则会重传分组,即超时重传
连续 ARQ 协议:
-
滑动窗口协议 与 自动重传请求技术结合形成连续 ARQ 协议。连续 ARQ 协议根据超时重发数据方式的不同分为
后退N帧ARQ协议
和选择重发ARQ协议
-
发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。
-
接收方一般都是采用
累积确认(ACK机制)
的方式。这就是说接收方不必对收到的分组逐个发送确认,而是可以在收到几个分组后对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了
后退N帧 ARQ(Go-Back-N ARQ)
#
GBN 是在发送完一个数据帧后,不停下来等待确认帧,而是可以连续再发若干帧,边发可以边等待确认帧,如果收到了确认帧,又可以继续发送数据帧, 由于减少了等待的时间,利用率就提高了。但是如果接收到错误帧的话,所有该帧后面的帧都要重发
选择性重发/拒绝 ARQ (Selective Repeat/Reject ARQ)
#
相对于后退 N 帧 ARQ,在收到错误帧的情况下不需要再重传所有的,只需要选择错误的帧进行重发,进一步提高了复用率。但同时牺牲了空间,因为它需要将已经接收到的正确的信息缓存下来,直到所有信息正确被接收到然后再发送确认收到
流量控制#
通过 TCP 连接发送数据,如果发送方发送数据很慢,容易造成资源浪费;如果发送方发送数据过快,接收方来不及接收会造成数据丢失。流量控制就是指在接收方能够接收的范围内,合理而又快速的发送数据。
基于滑动窗口的流量控制#
在 TCP 连接建立时,接收方会在确认报文段中给出自己接收窗口的大小。在每次发送确认报文时能够根据情况动态调整接收窗口的大小,并将告知发送方。如下图所示:
发送方发送序号从 1 开始的 100 字节的数据,接收方在确认报文中声明自身的接收窗口大小为 300 字节。之后发送方发送 300 字节数据,接收方在确认报文中声明自身接收窗口大小调整为 50 字节。发送方再发送 50 字节数据之后,收到接收方传来的确认报文,在该报文中声明接收窗口为 0。
在接收方接收窗口为 0 时,发送方不再发送数据,直到接收方发送确认报文表明窗口大小发生改变。可是这个确认报文不一定能够被发送方接收到,如果一旦该确认报文丢失,双方都将处于等待中,形成死锁。为防止这种情况出现,TCP 规定在收到对方接受窗口为 0 时,启动一个坚持定时器周期性的发送探测报文,以确定对方接收窗口为 0 的状态是否改变
另外,TCP 标准规定:接收方接收窗口为 0 时,不再接收正常数据,但是可以接收零窗口探测报文段、确认报文段、携带紧急数据的报文段
拥塞控制#
TCP 进行拥塞控制常用的算法有四种:慢启动
、拥塞避免
、快重传
、快恢复
慢启动#
TCP 为发送方维持一个拥塞窗口,记为 cwnd, 拥塞窗口的值跟 SMSS 有关,SMSS 为发送的最大报文段长度。
慢启动算法规定:拥塞窗口初始化后,每收到一个对新报文的确认,拥塞窗口就加一个 SMSS 的大小。拥塞窗口以字节为单位,但是慢启动以 SMSS 大小为单位增加。按照慢启动算法,经过一轮传输,拥塞窗口就增大一倍,这是一种指数增长的关系
拥塞避免#
慢启动算法除了维持拥塞窗口 cwnd 变量之外,还维持另一个变量慢启动门限 ssthresh。当 cwnd 以指数增长的形式增长到大于或等于 ssthresh 时,就不再采用慢启动算法,而是采用拥塞避免算法来进行拥塞控制。
拥塞避免算法规定:每次收到一个确认时将 cwnd 增加 1/cwnd 个 SMSS。即不再是像慢启动算法那样经过一轮传输 cwnd 翻倍了,而是经过一轮传输增加一个 SMSS。这是一种加性增长的关系,当拥塞发生时(超时或收到重复确认),cwnd 被设置为 1 个 SMSS。ssthresh 被设置为当前窗口大小的一半,但最少为 2 个报文段
总结就是:加性增,乘性减
快重传#
如果个别报文段在网络中丢失,网络并没有发生拥塞,这种情况下发送方收不到确认报文,在超时之后会重传该报文。发送方误以为网络发生拥塞,错误的启动慢开始算法,降低了传输效率。
采用快重传算法可以让发送方尽早知道个别报文段的丢失。快重传算法要求接收方不要延时发送确认,即使收到失序的报文段也要立刻发送对已收到报文的重复确认。如下图所示:
接收方收到 M1 之后发送对 M1 的确认报文,M2 报文丢失,之后接收方收到 M3、M4、M5 时每次都发送对 M1 报文的重复确认。快重传算法规定当收到三次重复确认后,发送方就认为 M2 报文段丢失,立即重传 M2 报文段,而不用等待超时时再重传,这样可以避免发送方误认为网络发生拥塞
快恢复#
在快重传算法执行后,发送方知道只是丢失个别报文,而不是网络发生拥塞。之后并不会执行慢启动算法,而是执行快恢复算法:调整门限值 ssthresh = cwnd/2,同时设置 cwnd = ssthresh + 3 SMSS。设置拥塞窗口的值为门限值加 3 个报文段是因为发送方收到三个确认报文,就认为有三个分组已经离开网络到达接收方的缓存,这三个确认报文不再占用网络资源,可以适当增大拥塞窗口的大小
拥塞控制和流量控制的区别#
-
拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况
-
流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的
五、TCP 和 UDP 的区别#
- TCP 面向字节流,UDP 面向报文;
- TCP 面向连接(需要三次握手),UDP 面向非连接;
- TCP 提供可靠的数据传输服务,有丢包重传机制且保证数据顺序,UDP 可能会丢包也不保证数据顺序
- 每一条 TCP 连接只能是点到点的;UDP 支持一对一,一对多,多对一和多对多的交互通信
- TCP 要求系统资源较多,UDP 较少
具体编程时的区别,socket () 的参数不同
- UDP Server 不需要调用 listen 和 accept
- UDP 收发数据用 sendto/recvfrom 函数
- TCP:地址信息在 connect/accept 时确定
- UDP:在 sendto/recvfrom 函数中每次均 需指定地址信息
- UDP:shutdown 函数无效
六、HTTP 协议#
HTTP 协议是超文本传输协议的缩写,英文是 Hyper Text Transfer Protocol。它是从 WEB 服务器传输超文本标记语言 (HTML) 到本地浏览器的传送协议,基于 TCP/IP 通信协议来传递数据
报文格式#
常见请求头#
Accept
:用于高速服务器,客户机支持的数据类型Accept-Charset
:用于告诉服务器,客户机采用的编码格式Accept-Encoding
:用于告诉服务器,客户机支持的数据压缩格式Accept-Language
:客户机的语言环境Host
:客户机通过这个头高速服务器,想访问的主机名If-Modified-Since
:客户机通过这个头告诉服务器,资源的缓存时间Referer
:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的(防盗链)User-Agent
:客户机通过这个头告诉服务器,客户机的软件环境Cookie
:客户机通过这个头可以向服务器带数据Connection
:处理完这次请求后是否断开连接还是继续保持连接Date
:当前时间值
常见响应头#
Location
: 表示重定向的地址,该头和 302 的状态码一起使用。Server
: 表示服务器的类型Content-Encoding
: 表示服务器发送给浏览器的数据压缩类型Content-Length
: 表示服务器发送给浏览器的数据长度Content-Language
: 表示服务器支持的语言Content-Type
: 表示服务器发送给浏览器的数据类型及内容编码Last-Modified
: 表示服务器资源的最后修改时间Refresh
: 表示定时刷新Content-Disposition
: 表示告诉浏览器以下载方式打开资源(下载文件时用到)Transfer-Encoding
: 告诉浏览器数据的传送格式Set-Cookie
: 表示服务器发送给浏览器的 cookie 信息(会话管理用到)Expires
: 告诉浏览器把回送的资源缓存多长时间 -1 或 0 则是不缓存Cache-Control
: no-cachePragma
: no-cache
服务器通过以上两个头,也就是控制浏览器不要缓存数据Connection
: 表示服务器和浏览器的连接状态。close:关闭连接 keep-alive: 保存连接
请求状态码#
状态码分类#
- 1XX- 信息型,服务器收到请求,需要请求者继续操作。
- 2XX- 成功型,请求成功收到,理解并处理。
- 3XX - 重定向,需要进一步的操作以完成请求。
- 4XX - 客户端错误,请求包含语法错误或无法完成请求。
- 5XX - 服务器错误,服务器在处理请求的过程中发生了错误
常见请求状态码#
200
OK 请求已成功204
No Content 无内容,服务器成功处理了请求没有返回任何内容301
Moved Permanently 被请求的资源已移动,永久重定向302
Found 已找到,临时重定向304
Not Modified 未修改,客户的缓存资源是最新的,要客户端使用缓存400
Bad Request 客户端请求有语法错误,不能被服务器所理解401
Unauthorized 未授权,未授权客户机访问数据403
Forbidden 禁止,没有权限访问404
Not Found 请求资源不存在,可能是输入了错误的 URL405
Method Not Allowed 方法不允许406
Not Acceptable 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体500
Internal Server Error 内部服务器错误502
Bad Gateway 无效网关,作为网关或者代理的服务器执行请求时接收到无效的响应503
Service Unavailable 服务不可用,服务器由于维护或者负载过重未能应答504
Gateway Timeout 网关连接超时,网关或者代理的服务器无法在规定的时间内应答
Post 和 Get 请求的异同#
-
GET 请求的数据会附在 URL 之后(就是把数据放置在 HTTP 协议头中),以?分割 URL 和传输数据,参数之间以 & 相连。POST 把提交的数据则放置在是 HTTP 包的包体中
-
Get 可提交的数据量较小 (因为数据附在 URL 之后)、而 Post 提交的数据量较大,浏览器和服务器会有不同的限制
-
Post 安全性比 Get 高,GET 的数据在 URL 中对所有人都是可见的;说 Get 是安全的指的仅仅是非修改信息,Get 用于获取 / 查询资源信息,Post 用于更新资源信息
-
GET 是幂等的,POST 不是
-
GET 编码类型 application/x-www-form-url,POST 编码类型 encodedapplication/x-www-form-urlencoded 或 multipart/form-data
-
GET 历史参数保留在浏览器历史中。POST 参数不会保存在浏览器历史中
幂等性#
HTTP 方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。即:同一个请求,发送一次和发送 N 次效果是一样的!
幂等的方法:GET、DELETE、PUT
PUT 与 POST 均是创建或更新,唯一不同是 POST 非幂等
http1.x/2.0#
http1.1#
-
引入了持久连接( persistent connection),即 TCP 连接默认不关闭,可以被多个请求复用,不用声明 Connection: keep-alive。
-
引入了管道机制( pipelining),即在同一个 TCP 连接里,客户端可以同时发送多个
-
请求,进一步改进了 HTTP 协议的效率。
-
新增方法:PUT、 PATCH、 OPTIONS、 DELETE。
-
http 协议不带有状态,每次请求都必须附上所有信息。请求的很多字段都是重复的,浪费带宽,影响速度
http2.0#
-
http/2 是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为 "帧"(frame):头信息帧和数据帧。 避免 http1.x 在传输数据时明文传输内容容易导致的安全性问题
-
复用 TCP 连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,避免了队头堵塞的问题,此双向的实时通信称为多工( Multiplexing)。
-
HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送。
-
引入头信息压缩机制( header compression) , 头信息使用 gzip 或 compress 压缩后再发送
https#
HTTPS 经由 HTTP 进行通信,利用 SSL/TLS 协议来加密数据包,是 HTTP 的安全版,与 http 主要区别:
- HTTPS 协议需要到 CA 申请证书
- HTTP 和 HTTPS 使用端口不一样,前者是 80,后者是 443
- HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,HTTPS 运行在 SSL/TLS 之上,SSL/TLS 运行在 TCP 之上,所有传输的内容都经过加密的
- HTTPS 可以有效的防止运营商劫持
七、浏览器输入域名到展示页面过程#
事件顺序:
- DNS 域名解析:浏览器缓存 --> 操作系统缓存 --> 本地 host 文件 --> 路由器缓存 --> ISP DNS 缓存 --> 顶级 DNS 服务器 / 根 DNS 服务器,查找域名对应的 IP 地址
- 建立 TCP 连接: TCP 采用三次握手与服务器建立连接,提供可靠的传输服务
- 发送 HTTP 请求:通过 TCP 连接把 HTTP 报文发送给服务器
- 服务器处理请求并返回 HTTP 报文
- 浏览器渲染页面:首先浏览器解析 HTML 文件构建 DOM 树,然后解析 CSS 文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕
涉及到的协议:
-
应用层:HTTP (WWW 访问协议),DNS (域名解析服务)
DNS 维护着 域名 (domain name) 和 IP 地址 (IP address) 的对照表表,以解析消息的域名。 -
传输层:TCP (为 HTTP 提供可靠的数据传输),UDP (DNS 使用 UDP 传输)
-
网络层:IP (IP 数据数据包传输和路由选择),ICMP (提供网络传输过程中的差错检测),ARP (将本机的默认网关 IP 地址映射成物理 MAC 地址)
八、session 和 cookie 区别#
-
cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
-
cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗
-
考虑到安全应当使用 session。
-
session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用 COOKIE。
-
单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie
补充#
session 在一定程度上依赖于 cookie。服务端执行 session 机制时候会生成 session 的 id 值,这个 id 值会发送给客户端,客户端每次请求都会把这个 id 值放到 http 请求的头部发送给服务端,而这个 id 值在客户端会保存下来,保存的容器就是 cookie
九、长连接和短连接与 WebSocket#
长连接和短连接#
长连接和短连接区别#
在 HTTP/1.0 中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次 HTTP 操作,就建立一次连接,但任务结束就中断连接。
从 HTTP/1.1 起,默认使用长连接,用以保持连接特性。使用长连接的 HTTP 协议,会在响应头设置:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
HTTP 协议的长连接和短连接,本质上是 TCP 协议的长连接和短连接
长连接和短连接应用场景#
-
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个 TCP 连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就 OK 了,不用建立 TCP 连接。 例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成 socket 错误,而且频繁的 socket 创建也是对资源的浪费。
-
而像 WEB 网站的 http 服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像 WEB 网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。 所以并发量大,但每个用户无需频繁操作情况下需用短连接好
短轮训和长轮训#
和短连接和长连接有本质区别。长、短连接是客户端与服务端建立和保持 TCP 连接的机制;而长、短轮询是指客户端请求服务端,服务端给予应答的方式。
-
短轮询:重复发送 Http 请求,查询目标事件是否完成,优点:编写简单,缺点:浪费带宽和服务器资源
-
长轮询:在服务端 hold 住 Http 请求(死循环或者 sleep 等等方式),等到目标时间发生 (保持这个请求等待数据到来或者恰当的超时),返回 Http 响应。优点:在无消息的情况下不会频繁的请求,缺点:编写复杂
WebSocket#
WebSocket 连接建立#
客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息 “Upgrade: WebSocket
” 表明这是一个申请协议升级的 HTTP 请求
WebSocket 和 HTTP 长连接区别#
- HTTP1.1 通过使用 Connection进行长连接,HTTP 1.1 默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求,但是对每个请求仍然要单独发 header,Keep-Alive 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如 Apache)中设定这个时间。
- websocket 的长连接,是一个真的全双工,第一次 tcp 链路建立之后,后续数据可以双方都进行发送,不需要发送请求头,并且这个连接会持续存在直到客户端或者服务器端的某一方主动关闭连接,与 HTTP 长连接不同,WebSocket 可以更灵活的控制连接关闭的时机,而不是 HTTP 协议的 Keep-Alive 一到,服务端立马就关闭(这样很不人性化)