# TCP/IP 四层模型,OSI 七层模型
# TCP 连接建立(三次握手)
- 客户端(client)建立连接,
SYN=1
,发送后状态变成SYN_SEND
- 服务端(server)收到后,同意建立连接,
ACK=1, SYN=1
,发送完成后状态变成SYN_RCVD
- 客户端(client)收到后,状态变成
ESTABLISHED
,返回ACK=1
给服务端;服务端(server)收到后,状态也变成ESTABLISHED
,连接建立成功.
TCP 连接建立为什么是 3 次,不是两次或者四次?
- TCP 是全双工传输模式,它们双方即是客户端也是服务端,需要建立双向的连接;如果只有两次,无法做到双向连接,而建立连接时,服务端发送确定的同时将
SYN=1
,确认和建立连接的请求合并了,所以也不需要 4 次.
# 半连接队列和 SYN Flood 攻击
半连接队列
服务端在
LISTEN
状态时,会在内部维护两个队列:- 半连接队列(
SYN队列
):三次握手未完成的连接(客户端发送SYN请求
,服务端接收后,便回复SYN和ACK
,状态由LISTEN
态变成SYN_RCVD
,此时这个连接就被推入半连接队列) - 全连接队列(
ACCEPT队列
):完成三次握手的连接(客户端回复ACK
,服务端接受后,三次握手完成,将连接从SYN队列
中推入ACCEPT队列
)
- 半连接队列(
SYN Flood
攻击一种典型的 DDos 攻击,在短时间呢伪造不存在的 IP,向服务端发送大量的
SYN
请求;当服务端发送SYN+ACK
报文后,不会收到ACK
回应报文,那么SYN队列
内的连接就不会出队,久而久之会沾满服务器的SYN队列
,使得正常用户无法正常访问.应对方案:
SYN代理防火墙
:对于每一个SYN请求
进行代理和回应,并保持半连接;等客户端返回ACK确认
后,再重新构造SYN
包到服务器,建立真正的 TCP 连接
# TCP 连接释放(四次挥手)
- 客户端(client)连接释放,向服务端发送释放连接请求,
FIN=1
,此时客户端没有数据需要发送,状态变成FIN_WAIT_1
- 服务端(server)收到后,返回一个确认报文
ACK=1
,服务端状态变成CLOSE_WAIT
(服务端可能还没有发送完数据) - 等到服务端(server)发送完所以数据后,向客户端发送连接释放请求,
FIN=1
,服务端状态变成LAST_ACK
- 客户端收到
ACK=1
确认之后,状态变成FIN_WAIT_2
;客户端收到服务端释放连接请求后,向服务端发送ACK=1
,此时客户端状态变成TIME_WAIT
, 等待 2MSL(报文最大生命周期)的时间,才会进入CLOSED
状态
为什么 TCP 连接释放不能 3 次?
- 因为
FIN=1
和ACK=1
不能同时发送,服务端在收到客户端FIN=1
后,数据可能没有发送完成.
# CLOSE_WAIT 与 TIME_WAIT
CLOSE_WAIT
状态的意义服务端收到客户端的关闭请求并确认之后,会进入
CLOSE_WAIT
状态。此时服务端可能还有一些数据需要发送,因此不会立马关闭连接,而CLOSE_WAIT
状态就是为了保证在服务端关闭之前将待发送的数据处理完TIME_WAIT
状态的意义客户端在收到客户端的关闭请求并确认之后,会进入
TIME_WAIT
状态- 防止旧连接的数据报影响新的连接. TCP 使用四元组区分连接(源端口、目的端口、源 IP、目的 IP). 如果新、旧连接的 IP 和端口完全一致,则内核协议栈无法区分这两条连接,在关闭 “上一个连接” 之后,立马又重新建立了一个相同的 IP 和端口号的 “新连接”,“前一个连接” 一些超时重传的重复的报文在 “前一个连接” 中断之后到达,而被” 新连接 “接收到.
2*MSL
的时间足以保证两个方向上的数据报都被丢失(如何客户端最后一次发送ACK确认
报文之后立马关闭连接,但是此时服务端对应的端口并没有关闭,此时客户端在相同的端口建立新的连接,可能会导致新连接接收到旧连接产生的数据报,导致一些错误) - 保证连接的正确关闭。如果客户端的最后一次
ACK确认
报文丢失,由于 TCP 超时重传机制,服务端会重发FIN报文
;若没有TIME_WAIT
状态的话,超时重传的FIN报文
所对应的连接已经关闭,导致服务端没有得到正常的关闭
为什么等待时间是
2MSL(Maximuxm Segment Lifetime)
- 保证客户端发送的最后一个
ACK
确认报文能够被服务器正确接收,时服务端可以安全的关闭连接。若最后一个ACK=1
报文丢失,在 2MSL 内客户端必定察觉,可以重发
# TCP 如何保证传输的可靠性
- 校验和:发送放在发送数据时会计算校验和,接收方在接受到数据后同样会检查校验和,如果不一致,那么传输发送了差错
- 确认应答、序列号:TCP 对数据报进行了编号,同时接收方在接受了到了后会发送
ack
的确认 - 超时重传:如果发送方一段时间没有收到某个报文的
ACK
确认,则会重新发送数据 - 连接管理:三次握手和四次挥手保证连接的建立和释放的可靠性
- 流量控制:TCP 协议报文包含 16 位的窗口大小,接收方在发送确认的同时会将自身窗口填入,发送方就根据报文中的窗口大小来控制发送速度
- 拥塞控制:
# TCP 的流量控制
- TCP 中的流量控制是通过一个可变的滑动窗口来实现的. TCP 报文段中的窗口大小表示从被确认的字节算起还可以发送的字节数
- 发送方的发送窗口内的字节都允许发送,当左部字节已发送并收到确认则窗口右移.
- 接受方的接收串口内的字节都允许被接收。当左部字节已经发送确认并收到发送方确认,则窗口右移.
TCP 流量控制是一个控制发送方发送速度,防止发送方发送速度过快导致接收方无法正确接受(缓存满),是一个局部的控制算法
# TCP 拥塞控制
- 拥塞控制的方法:慢开始,拥塞避免,快重传,快恢复
- 慢开始:不确定当前的网络状况,从 1 开始按指数逐渐增大拥塞窗口的大小,以此来探测当前网络的状况.
- 拥塞避免:拥塞窗口达到阈值时所采用的策略,拥塞窗口的大小线性增大
- 当出现了报文超时重传,当前拥塞窗口变成 1,重新执行慢开始,同时阈值减半
- 快重传:当收到三个重复的
ACK确认
时执行快重传,拥塞窗口减半,此时阈值设置为当前窗口的大小,进入快恢复 - 快恢复:
TCP 拥塞控制同样也是用于控制发送方发送速度,但是出发点是为了缓解整个网络的拥塞,是一个全局的控制算法.
- 防止旧连接的数据报影响新的连接. TCP 使用四元组区分连接(源端口、目的端口、源 IP、目的 IP). 如果新、旧连接的 IP 和端口完全一致,则内核协议栈无法区分这两条连接,在关闭 “上一个连接” 之后,立马又重新建立了一个相同的 IP 和端口号的 “新连接”,“前一个连接” 一些超时重传的重复的报文在 “前一个连接” 中断之后到达,而被” 新连接 “接收到.
# TCP 重传机制
- 超时重传
- 快速重传
- 选择确认重传
# ARQ 协议
ARQ:自动重传请求;如果发送方在发送后一段时间内没有收到确认,它通常会重新发送.
ARQ 协议有两种:
- 停止等待 ARQ
- 连续 ARQ 协议
- 停止等待 ARQ 协议:发送端维护一个超时计数器,发送端每次发送的报文在得到接收方的确认之后才可以发送下一个数据,超过一定时间没有收到发送方的确认,则需要重新发送。对于发送方收到了多个对同一报文的确认直接丢失。接收方对于接收到重复的报文也直接丢失.
- 连续 ARQ 协议:发送端会维护一个窗口,窗口内的分组可以连续发送出去而不需要等待接收端的确认。对于按需到达的分组,接收端会发送最后一个正确到达的分组的确认. (提高信道利用率),会出现回退 N 的现象(当发送端发送了 5 条消息,第三条消息丢失了,接收方只能给接收方发送前两个的确认,而不清楚后三条消息的状态,算法会选择吧后面的三条消息全部重传)
# TCP 与 UDP 的区别
- TCP 是面向连接的,提供可靠的数据流传输;UDP 是无连接的,数据传输不可靠
- TCP 是面向字节流的,UDP 面向报文
- TCP 提供了流量控制和拥塞控制,而 UDP 没有
- TCP 一般只支持点到点的通信,UDP 支持一对一,一对多的通信
- TCP 首部长度 20~60 字节,UDP 首部长度只有 8 字节
运行在 TCP 之上的协议:
HTTP
,HTTPS
,FTP
,SSH
运行在 UDP 之上的协议:DNS,TFTP
TCP 应用场景:实时性要求低,准确度要求高(文件传输,收发邮件,远程登录)
UDP 应用场景:实时性要求高,准确度要求低(在线语音 / 视频)
# TCP 中的粘包和拆包
一个完整的数据报可能会被 TCP 拆分成多个包进行发送,也可能把多个小的包封装成一个大的数据包发送
为什么会产生拆包和粘包
- TCP 是基于字节流的
- 要发送的数据大于 TCP 发送缓冲区剩余空间大小时,将会发生拆包
- 待发送的数据长度大于最大报文长度
MSS
(TCP 报文长度 + TCP 首部长度 > MSS),TCP 在传输过程中会发生拆包 - 要发送的数据小于 TCP 发送缓冲区大小时,将会发生粘包
- 接收端没有及时读取接收端缓存内的数据,将会发生粘包
如何解决
- 在数据尾部增加特殊的字符进行分割
- 发送端将每个数据包封装成固定大小
- 将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小
# TCP 校验和采用什么算法
# 既然 TCP 保证了可靠传输,为什么应用层还需要做校验?
TCP
的传输确认机制是可靠的,但是TCP
的数据完整性的效验是不可靠的TCP
能保证端到端的正确传输,但是交付到应用程序,应用程序是否能做出正确的处理(程序是否有bug
)TCP
无法保证,需要应用层自己保证- 设备故障,写入缓存的数据丢失
# 浏览器请求一个网址的过程
- 首先通过
DNS
将域名解析为IP地址
- 与服务器通过三次握手,建立 TCP 连接
- 服务器处理 http 请求,返回 http 响应
- 浏览器解析并渲染页面
- TCP 四次挥手断开连接
这个过程所使用的协议:
- DNS
- TCP
- IP
- OPSF
- ARP
- HTTP
# http 协议中请求的方式
GET
、POST
、HEAD
、PUT
、DELETE
# 常用的服务对应的端口
FTP
:21ssh
:22HTTP
:80HTTPS
:443MySQL
:3306
# GET 与 POST 的区别
- 安全性:
GET
提交的数据会出现在 URL 内,相对不安全;POST
提交的数据会在报文体内,相对安全 - 数据流:
GET
传输的数据受限与 URL 的长度,而POST
没有这种限制 - 一般而言
GET
从服务器上获取资源,而POST
更新服务器上的资源
# http 响应码
1××
:提示信息,表示协议处于中间状态2××
:成功,报文被正确的接收和处理3××
:重定向,资源位置发生变动,需要客户端重新发送请求(301
永久性移动,302
临时性移动)4××
:客户端错误,请求的报文有误,服务器无法处理5××
:服务端错误
# http 有哪些常见的字段
HOST
:服务器域名Content-Length
:服务器返回响应时,该字段表示回应的数据长度
# 如何理解 http 协议的 "无连接,无状态"
无状态:在 http 协议中服务端不会保留客户端的任何信息
浏览器第一次发送请求给服务器时,服务器响应了;如果之后再次发送第二次请求给服务器,它还是会响应,但是服务器并不知道两次请求来着同一个客户端
# http 的长连接与短连接的区别
- 在早期的
http/1.0
默认使用的是短连接,每次客户端与服务端进行一次 http 操作,就建立一次连接,任务结束就中断连接 - 从
http/1.1
起,默认使用的长连接。响应报文中Connection:keep-alive
,keep-alive
具有一个保持时间.
# HTTP/1.0、1.1、2.0 的区别
HTTP/1.0
:默认短连接,可以设置Connection:keep-alive
强制长连接HTTP/1.1
:默认长连接HTTP/2.0
:采用了多路复用
# HTTPS 协议的流程
# http 与 https 的区别
http 的缺点
- 明文传输,内容可能被窃听
- 通信双方没有身份认证
- 无法验证报文的完整性
https 的改进
- 加密:客户端通过
SSL/TLS
将报文内容进行加密,服务端界面(运输层与网络层之间加上 SSL/TLS 网络协议) - 身份认证:通过值得信赖的第三方机构颁布的证书来确认双方的身份.
- 完整新保护。通过 MD5 等散列码进行通信内存的校验
https 主要工作流程
- 客户端发起 https 请求,连接到服务端的 443 端口
- 服务端将自己的数字证书发送给客户端()
- 加密:客户端通过
# Session 与 Cookie
cookie
:session
:区别:
Cookie
存储在客户端,Session
存储在服务端- 有效期不同.
Cookie
一般可以设置为长时间保持,Session
一般有效期较短
关联:
- 用户第一次请求服务器时,服务器根据用户提交的信息,创建响应的
Session
,并返回此Session
的唯一标识Session ID
给客户端;客户端在接收到服务器返回的Session ID
后将其保存在Cookie
中,同时绑定当前的域名. - 当用户第二次请求服务器时,请求会自动判断此域名狭隘是否存在
Cookie
信息,如果存在则自动将Cookie
信息发送给服务端;服务端会从Cookie
中获取Session ID
并查找对应的Session
信息,如果没有找到,说明用户没有登陆或者登陆失效,如果找到了,说明用户已经登陆可直接执行响应操作.
分布式环境下
Session
怎么处理?- 可以使用
Redis
等分布式缓存来存储Session
信息,在多台服务器之间共享
# DNS 域名系统
对于人而言记忆一串有意义的字符串要比记忆一组无规律的数字要容易的多;DNS,即为域名系统,是一个由域名到 IP 地址的分布式数据库,可以方便的完成域名到 IP 的转换.
- 工作原理
- 当用户输入域名时,浏览器先检查自己的缓存是否包含这个域名的映射。如有则解析结束
- 检查操作系统缓存中是否(Windows 的 hosts)有该域名的映射
- 向本地域名服务器发送解析请求,查找是否有对应的域名映射
- 本地域名服务器依次向根域名服务器、顶级域名服务器、权限域名服务器发送请求,直到找到域名的映射
# ARP 协议
网络层的 IP 报文向下需要封装成帧,需要添加以太网头部,这就需要知道节点的 MAC 地址;ARP 的作用就是完成 IP 地址到 MAC 地址的转化协议
- 首先每个主机都会维护一张 ARP 列表,用于存储 IP 地址到 MAC 地址的映射
- 源主机发送数据时,首先检查 ARP 列表内是否有目的地址的 MAC 地址,如果有,则写入以太网头部,并发送帧。如果没有,主机以广播的形式发送 ARP 数据报,数据报内源主机 IP 地址,源主机 MAC 地址,目的主机的 IP 地址
- 当网络中的主机收到 ARP 数据包时,首先检查报文中的 IP 地址是否是自己,如果不是则丢弃该报文;否则将自己的 MAC 地址写入 ARP 响应报文中,同时将源主机的 IP 地址和 MAC 地址键值对写入自己的 ARP 列表中.
- 源主机收到 ARP 响应报文后,将目的主机的 IP 地址和 MAC 地址写入自身的 APR 列表中,并写入以太网头部,发送该帧.
# IPV4 地址不够如何解决
DHCP
:动态主机配置协议。动态分配 IP 地址,只给接入网络的设备分配 IP 地址.NAT
:网络地址转换协议.IPV6
:
# 为什么既有 MAC 地址,又有 IP 地址
# ICMP 协议
面向无连接,用于传输错误报告控制信息
ICMP差错报告报文
:终点不可达、时间超时、改变路由、参数问题ICMP询问报文
# 对称秘钥加密和非对称秘钥加密
对称秘钥加密
加密和解密使用同一种秘钥,运算速度快,但是无法安全的将秘钥传递给通信方
非对称加密
加密和解密使用不同的秘钥,运算速度慢
通信方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信的内容后使用私有密钥解密
# Liunx 下网络配置
ifconfig
或ip
# 参考博文
- [1] 面渣逆袭:计算机网络六十二问,三万字图文详解!速收藏! (qq.com)
- [2] 计算机网络 - 01-20 | 阿秀的学习笔记 (interviewguide.cn)
- [3] 2W 字!梳理 50 道经典计算机网络面试题(收藏版) (qq.com)