1. 计算机网络分层:
1.1. 应用层
- 应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。
- 应用层协议:不同端的应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。不同的网络应用需要不同的应用层协议。
- 应用层协议举例:
- 域名系统DNS
- 支持万维网应用的 HTTP协议
- 支持电子邮件的 SMTP协议
我们把应用层交互的数据单元称为报文。
1.2. 运输层
运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。
应用进程利用该服务传送应用层报文。“通用的”指的是多种应用使用同一个运输层服务。
同一个主机同时运行多个线程,因此运输层有复用和分用的功能。
- 复用:多个应用层进程可同时使用下面运输层的服务;
- 分用:运输层把收到的信息分别交付上面应用层中相应的进程。
运输层主要使用以下两种协议:
- 传输控制协议TPC:提供面向连接的,可靠的数据传输服务;
- 用户数据协议UDP:提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
1.3. 网络层(IP层)
在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。
网络层的任务就是选择合适的网间路由和交换结点, 确保数据及时传送。
发送数据时,网络层把传输层产生的报文段或用户数据报封装成分组和包进行传送(传送IP数据报)。
在TCP/IP体系结构中,由于网络层使用IP协议,因此分组也叫IP数据报。
互联网使用的网络层协议是无连接的网际协议和路由选择协议,因此互联网的网络层也叫做网际层或IP层。
1.4. 数据链路层
数据链路层简称为链路层。两台主机之前的数据是在链路上传送的,需要专门的链路层协议。
数据链路层将网络层叫下来的IP数据包组装成帧,在两个相邻节点的链路上传送帧。
帧包括数据和必要的控制信息(同步信息、地址信息、差错控制等)
数据链路层需要检错和纠错,因此需要采用可靠地传输协议来纠错。
1.5. 物理层
物理层传送的数据单位是比特(1个字节=8个比特,比特是计算机存储的最小单位)。
物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质与物理设备的差异。
“比特流的透明传送”表示经过实际电路传送后的比特流没有发生变化,就好像电路是看不见的。
1.6. 表格总结
分层 | 传输内容 | 协议 | 作用 |
---|---|---|---|
应用层 | 报文 | HTTP、FTP、域名系统、SMTP等 | 通过不同主机的进程交互来完成特定网络应用 |
运输层 | 应用层报文 | TCP/UDP | 为两台主机进程之间的通信提供通用的数据传输服务 |
网络层 | IP数据报 | IP协议 | 选择合适的网间路由和交换节点 |
数据链路层 | 帧 | 可靠性传输协议 | 在相邻节点的链路上传送帧 |
物理层 | 比特流 | / | 实现相邻节点间的比特流的透明传送 |
2. TCP 3次握手和4次挥手
2.0. TCP报文首部
符号 | 含义 |
---|---|
源端口和目的端口 | 各占2个字节,分别写入源端口和目的端口 |
序号(seq) | 占4个字节,TCP连接中传送的字节流中的每个字节都按顺序编号。例如,一段报文的序号字段值是 301 ,而携带的数据共有100字段,显然下一个报文段(如果还有的话)的数据序号应该从401开始 |
确认号(ack) | 占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701; |
终止FIN | 用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放 |
同步SYN | 在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1 |
确认ACK | 仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1 |
推送PSH | 当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1 |
复位RST | 当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接 |
紧急URG | 当URG=1,表明紧急指针字段有效。告诉系统此报文段中有紧急数据 |
窗口 | 占2字节,指的是通知接收方,发送本报文你需要有多大的空间来接受 |
检验和 | 占2字节,校验首部和数据这两部分 |
紧急指针 | 占2字节,指出本报文段中的紧急数据的字节数 |
选项 | 长度可变,定义一些其他的可选的参数 |
数据偏移 | 占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远 |
保留 | 占6位,保留今后使用,但目前应都位0 |
2.1. 三次握手
目的:建立可靠的通信信道,双方确认自己与对方的发送和接收是正常的。
- 第一次握手:客户端发送带有SYN标志的数据包以及初始序号seq=x,并进入SYN-SENT(同步已发送状态)。服务端接收到后可以确认自己的接收和对方的发送是正常的。
- 第二次握手:服务端发送带有SYN/ACK标志的数据包,以及确认号ack=x+1(),以及自己的初始序号seq=y,并进入SYN-RCVD(同步收到状态)。客户端接收到后可以确认双方的发送和接收都是正常的。
- 第三次握手:客户端发送带有ACK标志的数据包,以及确认号ack=y+1,以及序号seq=x+1,客户端进入ESTABLILSHED(已建立连接状态)。服务端接收到后可以确认双方的发送和接收是正常的,并进入ESTABLISHED状态,双方可以开始通信。
客户端和服务端都维护了一个自己的序号,记录自己发送内容的长度;
发送的确认号则为连接以来成功接收内容的长度+1,即对方下一次发送内容的起始字节位置。
三次握手后客户端和服务端都确认双方的接收和发送功能是正常的,此时建立的通信信道安全可靠。
TCP规定:
SYN报文段(SYN=1的 报文段)不能携带数据,但需要消耗一个序号;
ACK报文段可以携带数据,,但如果不携带数据则不消耗序号。
2.2. 第二次握手传回了ACK,为什么还要传回SYN?
服务端传回ACK:服务端告诉客户端确认收到来自客户端的信号,传回ACK=1才能使ack确认号有效。
服务端传回SYN:同意连接,确认并建立从服务端到客户端的通信。
就好像客户端给服务端打电话,服务端接了电话(ACK),然后还得告诉客户端自己现在有空(SYN),才能开启聊天内容。
2.3. 为什么TCP客户端最后还要发送一次确认?
- 为了让服务端确认自己的发送功能和客户端的接受功能正常。
- 防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
2.3. 四次挥手
第一次挥手:客户端发送一个连接释放报文FIN=1以及序号seq=u(等于前面已经传送过来的数据的最后一个字节的序号+1),用来关闭客户端到服务端的数据传送,此时客户端进入FIN-WAIT-1(等待终止1)状态;
第二次挥手:
- 服务端收到连接释放报文,
- 发回一个ACK=1以及确认号ack=u+1,并带上自己的序号seq=v。
- 此时服务端进入了CLOSE-WAIT(关闭等待)状态。客户端向服务端的方向释放了,处于半关闭状态(客户端已经没有数据要发了),服务器如果发送数据,客户端会接收。
- 客户端收到服务器的确认请求后,
- 客户端就进入了FIN-WAIT-2(等待终止2)状态,等待服务器发送连接释放报文(此时先接收有可能的来自服务端的最后数据)。
第三次挥手:
- 服务器将最后的数据发送给客户端;
- 向客户端发送连接释放报文FINK=1,确认号ack=u+1,然后进入LAST-ACK(最后确认)状态,等待客户端的确认。
第四次挥手:
- 客户端收到服务端的连接释放报文后
- 发出确认,ACK=1, ack=w+1, 自己的序列号seq=u+1
- 客户端进入了TIME-WAIT(时间等待)状态
- 此时TCP还没有释放,经过2*MSL(最长报文寿命)的时间后,
- 当客户端撤销相应的TCB后,进入CLOSE状态
- 服务端收到客户端发出的确认,立即进入CLOSED状态。撤销TCB后,结束了这次TCP连接
TCP规定:
FIN报文段即使不携带数据,也要消耗一个序号。
2.4. 为什么客户端最后还要等待2MSL
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
第一:保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二:防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
2.5. 如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
3. TCP和UDP的区别
类型 | 特点 | 性能 | 应用场景 | 首部字节 | |||
---|---|---|---|---|---|---|---|
面向连接? | 传输可靠性 | 传输形式 | 传输效率 | 所需资源 | |||
TCP | 是 | 可靠 | 字节流 | 慢 | 多 | 要求通信数据可靠 如文件传输、邮件 |
20~60 |
UDP | 无连接 | 不可靠 | 数据报文段 | 快 | 少 | 要求通信速度高 如域名转换 |
8个字节 |
UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。在即时通信如:微信语音,直播等方面很有效;
TCP 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。
4. TCP协议如何保证可靠传输
- 应用数据被分割成 TCP 认为最适合发送的数据块。
- TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
- 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
- TCP 的接收端会丢弃重复的数据。
- 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
- 拥塞控制: 当网络拥塞时,减少数据的发送。
- ARQ协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
- 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
4.1. ARQ协议
自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待ARQ协议和连续ARQ协议。
4.2. 滑动窗口和流量控制
TCP利用滑动窗口实现流量控制。控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
流量控制是点对点通信量的控制。
4.3. 拥塞控制
拥塞:某短时间,对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏。
拥塞控制:防止过多的数据注入到网络中,使网络中的路由器或链路不至于过载。
拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。
TCP发送方维持一个拥塞窗口(cwnd)的状态变量:
- 其大小取决于网络的拥塞程度,并且动态变化;
- 发送方让自己的发送窗口取min(拥塞窗口,接收方接受窗口)。
拥塞控制的算法:慢开始、拥塞避免、快重传、快恢复。
- 慢开始
主机开始发送数据时,由小到大地增大发送窗口,也就是由小到大地增大拥塞窗口数值(从1开始),每传播一次,cwnd翻倍;
- 拥塞避免:让拥塞窗口cwnd缓慢增大,每经过一个往返时间RTT就把发送方的cwnd+1;
- 快重传与快恢复:Fast Retransmit and Recovery(FRR)
- 当有单独的数据包丢失时,避免暂停,快速的重传和恢复丢失数据包;
- 当有多个数据信息包在某一段很短的时间内丢失时,它则不能有效工作。
5. 从输入URL到页面加载发生了什么?
5.1. DNS解析
- 网址 -> IP地址, 是个递归查询的过程
- 比如查找 www.google.com 是 com -> google.com -> www.google.com 的查找过程。由于省略了根域名服务器(.),所以浏览器在请求DNS的时候会自动加上,网址的真正解析过程是: com. -> google.com. -> www.google.com.。
- DNS负载均衡:访问同一个网址,每次访问的ip地址未必相同。
5.2. TCP连接
- HTTP协议就是使用TCP作为其传输层协议的,当 TCP出现瓶颈时,HTTP也会收到影响。
- 服务端收到TCP报文时会解包提取出HTTP报文,HTTP报文时明文,容易泄露信息。
- 在HTTP报文进入TCP前用SSL或TLS对HTTP报文进行非对称加密。
- HTTPS相比于HTTP提供了安全保证,但也增加了时间开销。
5.3. 发送HTTP请求
- HTTP协议发送到服务器80/8080端口,HTTPS协议发送到443端口
- HTTP请求报文由3部分组成:请求行,请求报头和请求正文。
- 请求行常用方法:GET,POST,PUT,DELETE,OPTIONS,HEAD。
- 常见请求报头有:Accept,Accept-Charset,Accept-Encoding,Cookie,User-Agent。
- 请求正文的数据格式需要在请求包头中设置。
5.4. 服务器处理请求并返回HTTP报文
HTTP响应报文由状态码、响应报头和响应报文组成
- 状态码:由3位数组成,第一个数字定义了相应级别,有5种可能取值:
- 1xx:指示信息——请求已接收,继续处理
- 2xx:成功——表示请求已被成功接收、理解、接受。(200,请求成功)
- 3xx:重定向——要完成请求必须进行更进一步的操作。
- 4xx:客户端错误——请求有语法错误或请求无法是实现。(404 not found)
- 5xx:服务器端错误——服务器未能是实现合法的请求。
- 常见状态码:200,204,301,302,400,401,404,500
- 响应报头:常见响应报头字段:Server,Connection
- 响应报文:服务器返回给浏览器的文本信息,通常HTML,CSS,JS,图片等文件就放在这一部分。
5.5. 浏览器解析渲染页面
5.6. 连接结束
6. 各协议与HTTP协议之间的关系
7. HTTP长连接,短连接
7.1. 短连接
在HTTP/1.0中默认使用短连接。
短连接:客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
7.2. 长连接
从HTTP/1.1起,默认使用长连接
用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
8. HTTP是不保存状态的协议,如何保存用户状态
- HTTP 协议是一种无状态协议,自身不对请求和响应之间的通信状态进行保存。
- 用Session机制,通过服务端记录用户的状态。
- 服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了
- 在服务端保存 Session 的方法很多,最常用的是内存和数据库(使用内存数据库redis保存)。大部分情况下通过在 Cookie 中附加一个 Session ID 来方式来跟踪。
当Cookie被禁用:利用URL重写把Session ID 直接附加在URL路径的后面
9. Cookie的作用,和Session有什么区别?
Cookie和Session都是用来跟踪浏览器用户身份的会话方式,应用场景不同。
Cookie一般用来保存用户信息:
- 下次访问自动填充信息
- 保持登录,下次访问不需要重新登录
- 登录后访问网站其他页面不需要登录
Session通过服务端记录用户的状态
Cookie的数据保存在客户端(浏览器端),Session的数据保存在服务器端
所以Session的安全性更好,Cookie不适合直接存储敏感信息,信息最好加密存储。
10. HTTP 1.0 和 HTTP 1.1的主要区别?
区别内容 | HTTP1.0 | HTTP1.1 |
---|---|---|
连接类型 | 默认使用短连接 | 默认使用长连接 |
错误状态响应码 | HTTP1.1新增了24个错误状态响应码 (409表示请求资源与资源当前状态发生冲突) (410表示服务器上的某个资源被永久性删除) |
|
缓存处理 | 使用header中的if-Modified-Since ,Expires作为缓存的判断标准 | 引用更多换从控制策略,例如:Entity tag, If-Unmodified-Since,If-Match等更多缓存头来控制 |
带宽优化及网络连接的使用 | 请求对象的某个部分会把整个对象发过去,并且不支持断点续传。 | 请求头引入了range头域,允许只请求资源的某个部分,方便开发者。 |
11. HTTP 和 HTTPS的区别
HTTP | HTTPS |
---|---|
起始默认端口为80 | 起始默认端口为443 |
HTTP运行在TCP协议之上,传输内容为明文 | HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS运行在TCP至上的,所有传输内容经过对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。 |
对称加密:密钥只有一个,加密解密为同一个密码,加密解密速度快,典型的对称加密算法有:DES、AES等
非对称加密:密钥成对出现,加密解密使用不同密钥,速度相对较慢,典型的非对称加密算法有:RSA、DSA等。
12. URI和URL的区别是什么
- URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。
- URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。
参考文献
TCP参考链接:https://blog.csdn.net/qzcsu/article/details/72861891
全文参考链接:https://github.com/Snailclimb/JavaGuide/blob/master/docs/network/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C.md