秋招面经笔记-计算机网络
OSI 七层模型
层级 | 功能 | 地址标识 | 常见协议 |
---|---|---|---|
物理层 | 在计算机之间传输比特流 | N/A | IEEE802.1A IEEE802.2——IEEE802.11 ... |
数据链路层 | 定义数据格式,保证数据传输的有效性 | MAC地址 | ARP RARP FDDI Ethernet Arpanet PDN SLIP PPP ... |
网络层 | 提供不同的网络之间的互联 | IP地址 | IP ICMP AKP UUCP ... |
传输层 | 提供端到端的数据传输服务 | 端口 | TCP UDP ... |
会话层 | 建立会话逻辑 | N/A | DNS ... |
表示层 | 标记数据格式(包括加密解密) | N/A | Telnet Rlogin SNMP Gopher ... |
应用层 | 各种应用软件 | N/A | HTTP TFTP FTP NFS WAIS SMTP ... |
TCP/IP五层模型
层级 | 功能 | 地址标识 |
---|---|---|
物理层 | 在计算机之间传输比特流 | N/A |
数据链路层 | 定义数据格式,保证数据传输的有效性 | MAC地址 |
网络层 | 提供不同的网络之间的互联 | IP地址 |
传输层 | 提供端到端的数据传输服务 | 端口 |
应用层 | 各种应用软件 | N/A |
通用
- 端口:
- 0-1023:知名端口,一般被现有服务占用
- 1024-65535:动态端口
- 在浏览器中键入域名,会发生什么(不考虑上下文,不完整)
- 浏览器查询缓存,如果有则直接使用缓存
- DNS查询:(缓存/
gethostbyname
/getaddrinfo
) - 创建套接字:(
socket
) - TCP三次握手:(
connect
) - 发送HTTP请求
- 服务器处理请求,返回响应结果
- (可能)TCP四次挥手,关闭套接字:(
close
) - 浏览器解析HTTP响应
- 请求到HTML后,递归请求HTML使用的资源文件
- 渲染页面
应用层
1. 常见协议
协议 | 全名 | 默认端口 | 使用传输层协议 |
---|---|---|---|
HTTP | 超文本传输协议 | 80 | TCP |
HTTPS | 超文本传输安全协议 | 443 | TCP |
Telnet | 远程登录服务的标准协议 | 23 | TCP |
FTP | 文件传输协议 | 20传输/21连接 | TCP |
TFTP | 简单文件传输协议 | 69 | UDP |
SMTP | 简单邮件传输协议 | 25 | TCP |
POP | 邮局协议 | 110 | TCP |
DNS | 域名解析服务 | 53 | TCP/UDP |
2. DNS
- 概念:DNS是域名和IP映射的大型分布式数据库,用户可以使用域名请求对应的IP地址,避免了记忆复杂的IP地址
- 使用TCP还是UDP:DNS协议使用UDP,但在区域传输(例如DNS之间数据同步)时会使用TCP,当查询数据量大于512字节时,DNS也会切换到TCP
- DNS查询方式:
- 递归查询:在递归查询中,当一个客户端向DNS服务器请求解析一个域名时,如果这个DNS服务器没有相关信息,它会代替客户端向其他服务器查询,直到获取到答案。然后,它会将结果返回给客户端。
- 迭代查询:迭代查询中DNS服务器不会代替客户端进行查询。相反,它会告诉客户端下一步应该查询哪个服务器。然后客户端会向这个新的服务器发送请求。这个过程会一直重复,直到找到答案。
- 查询流程
- 浏览器检查缓存,未命中则检查操作系统缓存(hosts)
- 操作系统未命中,则请求本地域名服务器解析(LDNS),通常使用递归查询
- LDNS缓存未命中,请求根域名服务器,返回给LDNS主域名服务器地址(gTLD),往后通常使用迭代查询
- LDNS查询gTLD,返回给LDNS域名对应的Name Server
- 查询Name Server,返回目标IP
- LDNS缓存,将结果交给用户
- 负载均衡:在DNS服务器中,为一个域名配备多个IP地址,分散请求,加快用户访问速度
3. HTTP
- HTTPS:由SSL加密,比HTTP更安全,需要CA证书,使用443端口(正常的HTTP使用80)
- 长/短连接:
- HTTP/1.0默认使用短连接,每次请求都需要重新建立TCP连接,使用Connection: keep-alive (非标准)可以维持连接
- HTTP/1.1后,默认使用长连接,使用Connection: close可以手动关闭连接
- HTTP请求并发问题:
- HTTP/2.0:Multiplexing可以同时进行多个请求。
- HTTP/1.1:单个TCP连接同时只能处理一个请求(可通过Pipeline技术完成多个请求同时发送,或者建立多个TCP连接,或维持TCP连接顺序处理多个请求)
- 请求方法:
- GET:请求指定的页面信息,返回实体主体(不接受请求体)(查)
- HEAD:同GET,但不实际返回内容,用于获取报头
- POST:提交数据,请求处理(可能导致资源的增改)(增)
- PUT:从客户端想服务器传送的数据,取代指定的文档内容(改)
- DELETE:请求服务器删除指定页面(删)
- CONNECT:HTTP/1.1协议中预留能将连接改为管道方式的代理服务器
- OPTIONS:允许客户端查询服务器性能
- TRACE:回显收到的请求,用于测试和诊断
- PATCH:用来对已知资源进行局部更新(PUT补充)(改)
- GET与POST的区别:
- 语义上GET只能做获取(无副作用),POST只能做增改(有副作用)
- GET只能使用URL传参,POST理论上可以使用URL或者使用请求体(请求体相对安全)
- GET提交的数据受到URL长度限制(由浏览器制约),POST理论上无限制
- 一般浏览器会主动缓存GET请求,POST不会(除非手动设置缓存策略)
- 理论上二者都只会产生一个数据包
- 请求报文:
- 请求行:POST /user/ HTTP/1.1
- 请求头:Content-Type: application/json
- 请求体:...
- 响应报文:
- 状态行:HTTP/1.1 200 OK
- 响应头:Content-Type: text/html
- 响应体:...
- Cookies:浏览器保存的一块键值对数据,用于在HTTP请求之间保存状态
- 会话Cookie:只保存在内存中,会话完成后即刻销毁
- 持久Cookie:保存在硬盘中,在有效期之前可一直使用
- Session:服务器存储的数据库,用于在HTTP请求之间保存状态,优点是存储在服务器中,安全性更好
- 服务器在登录等操作后会产生一个SessionID,通过响应Set-Cookie交给客户端
- 客户端每次访问都会包含该SessionID,标志当前用户
- SQL注入:在HTTP请求中注入恶意SQL代码
- 防御(Web):
- 输入有效性检查
- 防御(服务器):
- 不使用拼接字符串方法
- 使用预编译的PrepareStatement
- 输入有效性检查
- 过滤特殊字符
- 防御(Web):
- 缓存:
- 共有字段:可以被多个用户使用,一般存储在代理服务器 Cache-Control: public
- 私有字段:只能被单独用户使用,一般存储在浏览器中 Cache-Control: private
- 生命周期:max-age控制资源在缓存服务器中保存的时间 Cache-Control: max-age=31536000
- 生命周期(HTTP/1.0):使用Expires控制资源的过期时间 Expires: Wed, 04 Jul 2012 08:26:05 GMT
- 禁止缓存:不进行缓存 Cache-Control: no-store
- 禁止缓存:有效时才能使用该缓存 Cache-Control: no-cache
- 状态码:
- 1xx:信息性状态码
- 100:Continue
- 2xx:成功
- 200:Ok
- 204:No Content
- 206:Partial Content
- 3xx:重定向
- 301:Moved Permanently
- 302:Found
- 303 See Other
- 304:Not Modified
- 307:Temporary Redirect
- 4xx:客户端错误
- 400:Bad Request
- 401:Unauthorized
- 403:Forbidden
- 404:Not Found
- 5xx:服务器错误
- 500:Internal Server Error
- 503:Service Unavailable
- 1xx:信息性状态码
4. SSL/TLS
- 用户:非对称加密,保证套接字连接安全性
- 握手:
- client hello(可用版本,当前时间,客户端随机数,会话ID,可用密码套件,可用压缩方式)
- server hello(使用版本,当前时间,服务器随机数,会话ID,使用密码套件,使用压缩方式)
- server 证书 (可选)
- server hello done
- client 根据随机数计算密钥,通过加密(公钥或其他算法)交给服务器
- client 准备切换密码
- client 结束握手
- server 准备切换密码
- server 结束握手
- 切换到应用层协议
- 握手简易版:
- 服务端发送公钥
- 客户端根据公钥加密对称密钥
- 服务端根据私钥解锁对称密钥
- 双方使用对称密钥通信
- 公钥:公钥由数字证书提供,只要证书可信,公钥就是可信的
传输层
1. TCP
- TCP头:
- 源端口号(2bytes)
- 目的端口号(2bytes)
- 序号(4bytes):传输方向上字节流的字节编号初始值会被设置为一个随机数(ISN),之后每次发送,序号值都是ISN+数据在字节流中的偏移量,用于解决乱序问题
- 确认号(4bytes):接收方对发送方TCP报文的相应,其值是收到的序号值+1
- 首部长(4bits):标志首部长度(* 4bytes)
- 标志位(6bits):
- URG:标记紧急指针是否生效
- ACK:标志确认号是否有效,用于解决丢包问题
- PSH:提示接收端立刻从缓冲读走数据
- RST:表示要求对方重新建立连接
- SYN:表示请求建立一个连接
- FIN:表示关闭连接
- 窗口(2bytes):接收窗口,表示接收方缓存还有多少空间,用于解决流量控制
- 校验和(2bytes):CRC校验整个报文段是否损坏
- TCP状态
- CLOSED:初始状态
- LISTEN:服务器处于监听状态
- SYN_SEND:客户端发送SYN包(第一次握手)
- SYN_RECV:服务器收到SYN,发送SYN包(第二次握手)
- ESTABLISH:客户端收到SYN,发送ACK,服务端收到ACK(第三次握手)
- FIN_WAIT_1:终止连接的一方发送了FIN报文后进入(第一次挥手)
- CLOSE_WAIT:接收到FIN包后,立即回复ACK,但如果还有数据需要发送,则在数据发送完成之前处于该状态(第二次挥手)
- FIN_WAIT_2:收到FIN的ACK包,进入此状态(半连接)
- LAST_ACK:发送最后的FIN包,等待最后的ACK响应(第三次挥手)
- TIME_WAIT:发送最后的ACK,在此状态等待2MSL时间(第四次挥手)
- 三次握手:(
connect
)- 客户端发送SYN报文并指明ISN,客户端进入SYN_SEND状态
- 服务端以SYN应答,指定自己的ISN,把客户端的ISN+1作为ACK的值,服务端进入SYN_RECV状态
- 客户端发送ACK报文,将服务端ISN+1作为ACK的值,客户端进入ESTABLISH状态(可以携带数据)
- 四次挥手:
- 客户端发送FIN,客户端进入FIN_WAIT_1状态
- 服务端接收FIN,将客户端序列号+1作为ACK确认号,服务端进入CLOSE_WAIT,客户端收到后进入FIN_WAIT_2
- 服务端发送FIN,进入LAST_ACK状态
- 客户端接收FIN,将服务端序列号+1作为ACK确认号,客户端进入TIME_WAIT状态,等待2MSL进入CLOSED,服务端收到ACK进入CLOSED
- 为什么是三次握手:(
close
)- 第一次握手:确认客户端的发送能力
- 第二次握手:确认服务端的接收能力和客户端的发送能力
- 第三次握手:确认客户端的接收能力
- 如果没有第三次握手,可能会出现:客户端发送了两次SYN,第一次丢包,第二次受到SYN正常建立连接,连接关闭后,服务端收到了丢包(延迟)的SYN,与客户端(已经关闭)建立了连接,但什么都不做,浪费socket资源
- 为什么是四次挥手:
- 一方决定断开连接时,另一方很有可能有没有发完的报文,需要对方发完报文后主动断开才能保证通信的完整
- TIME_WAIT与2MSL:
- MSL是报文段的最大生存时间
- 确保ACK被服务端接收(ACK=1MSL,FIN重发=1MSL):如果客户端的最后ACK丢包了,服务端会重传FIN包,客户端会在2MSL内收到这个FIN包并重新响应
- 确保不会有任何旧包存在于网络中:MSL时间后,本次连接的所有包都会在网络中消失,确保新的连接不会受到干扰
Linux
系统调用:- 服务器:
socket
:创建套接字bind
:绑定本地端口listen
:进入监听状态accept
:等待连接read
:从socket读write
:向socket写close
:关闭套接字
- 客户端:
socket
:创建套接字connect
:连接服务器(三次握手)write
:向socket写read
:从socket读close
:关闭套接字(四次挥手)
- 服务器:
- 可靠性保证:
- 确认和重传:接收方收到报文会进行确认,发送方没有收到确认则重传
- 数据校验:TCP头有CRC校验和,检查数据是否损坏
- 数据分片和排序:TCP会按照MTU合理分片并标序,接收放会重新排序交给应用层
- 流量控制:接收方来不及处理时,通过滑动窗口降低发送方速率
- 拥塞控制:网络拥塞时通过拥塞窗口减少数据发送,防止丢包
- 拥塞控制:
- 慢启动:初始化拥塞窗口为1(可传递一个MSS大小的数据),每收到一个ACK,窗口+1,每过一个往返延迟时间RTT,窗口翻倍,窗口达到上限时(ssthresh)进入拥塞避免算法
- 拥塞避免算法:收到ACK,窗口=窗口+1/窗口,经过一个RTT,窗口+1
- 超时重传:将ssthresh设置为当前窗口的一半,窗口重置为1,进入慢启动
- 快速重传:窗口设置为当前窗口的一半,ssthresh设置为当前窗口,进入快速恢复算法
- 快速恢复算法:窗口+3(三个重复的ACK),重传指定数据包,如果再收到该ACK,窗口+1,收到新ACK,将窗口设置为ssthresh,进入拥塞避免算法
- 流量控制:
- 接收方通过TCP头窗口字段告知发送方本方可接受的最大数据量,解决发送方发送速率过快导致的接收方不能接收的问题
- 粘包/拆包:
- 问题:完整的业务可能会被TCP拆分成多个包发送,也有可能把多个小包封装成一个大包
- 原因:写入大小大于套接字缓冲区,进行MSS大小的TCP分段,以太网的payload大于MTU进行IP分片
- 解决方案:关闭Nagle算法,消息定长,包尾部添加特殊分隔符进行分割,消息中添加消息头和消息尾,使用其他协议(RTMP)
- DDOS:
- 不进行第三次握手,服务端一直等待确认数据包
- 预防:限制同时打开SYN半连接的数目,缩短SYN半连接的Timeout时间,关闭不必要的服务
- MTU:最大传输单元,由硬件规定,以太网的MTU为1500字节
- MSS:最大分节大小,TCP传输最大的数据分段大小,为MTU减去IPv4头和TCP头
- RTO:上一次发送数据,因为没有收到ACK而下一次重发的时间(重传间隔),通常是前一次重传间隔的两倍,到达上限后停止重传
- RTT:数据从发送到对方响应之间的间隔
- 与UDP区别:
- TCP面向连接,UDP无连接
- TCP提供可靠数据传输,UDP尽最大努力交付
- TCP面向字节流,UDP面向报文
- TCP有拥塞控制,UDP没有拥塞控制
- TCP点到点,UDP可以一对一,一对多,多对一和多对多
- TCP头开销20字节,UDP只有8字节
网络层
1. 常见协议
协议 | 全名 | 作用 |
---|---|---|
IP | 网际协议 | 定义数据基本单元和格式,定义数据提交方法和路由选择 |
ICMP | Internet控制报文协议 | 检测网络连接状况(错误侦测与回报) |
RIP | 路由信息协议 | 使用metric衡量达到目标地址的路由距离 |
IGMP | Internet组管理协议 | 实现组播,广播等通信 |
1. ICMP
- 差错报告报文类型:
- 终点不可达
- 时间超过
- 参数问题
- 改变路由
- 询问报文类型:
- 回送请求和回答(
ping
) - 时间戳请求和回答(返回当前时间)
- 回送请求和回答(
数据链路层
1. RARP
- 将MAC地址转换为IP地址
- 步骤:
- 读取自己的MAC地址,在网络中广播RARP请求
- RARP服务器收到请求,分配IP地址,将回应发送给主机
- 主机使用IP进行通讯