计算机网络笔记
常见的 HTTP 状态码有哪些?
HTTP 状态码为三位,主要分为五大类
- 1xx:初步响应。表示服务器接收到了初步的请求,可以继续请求,101 比如服务器同意升级协议,比如 HTTP TO WebSocket
- 2xx:表示请求成功,比如 201 表示资源创建完成,204 表示请求成功但是没有响应体
- 3xx:表示资源重定向:301 表示资源永久搬家,浏览器会记住新地址,302 表示临时搬家,资源还会再回来的,304 表示资源不变,调用本地缓存就行
- 4xx:客户端错误:比如 400 表示请求格式错误,401 表示没有登录或者 Token 过期,403 表示没有权限访问,比如普通用户访问管理员接口被打回来,404 表示资源没有被访问到
- 5xx:通常为服务器问题,500 表示服务器代码异常,比如 NULL 或者 SQL 链接错误等,502 表示网关拿到了无效响应,上游服务器挂了或者是格式不对,503 表示服务不可用,比如流量太大给服务器打掉了,504 上游服务超时了
HTTP 请求包含哪些内容,请求头和请求体有哪些类型?
首先,HTTP 请求包含请求行,请求头,请求体
- 请求行:包含请求方式,请求路径,请求协议,就是在浏览器上面看到的文本
- 请求头:包含一系列键值对,告诉服务器我是谁,浏览器版号,操作系统,或者一些本地验证信息
- 请求体:包含要提交给服务器的信息,
请求头和请求体之间用一个空行隔开,用于标记
请求头:
- 通用头部:请求和响应都可以使用,Cache-Control 控制缓存、Connection 控制连接是否保持
- 请求头部:用于请求,比如 Host 指定目标主机、User-Agent 标识客户端、Accept 告诉服务器想要什么格式、Authorization 带认证信息
- 实体头部:用于描述请求,比如请求的格式,请求体的大小
请求体格式:
- application/x-www-form-urlencoded:表单格式,最传统的格式,数据被编译成为:key=value 的形式
- multipart/form-data:上传文件使用的格式,数据使用分解符做分割
- application/json:JSON 格式,最常用的请求体格式
- text/plain:纯文本,很少用
- application/xml:XML,很少用
请求方法有什么?什么意思?
- GET:用于获取资源,幂等,不应该对服务器的数据造成更改,不应因为 GEt 操作影响后续 GET 操作
- POST:用于提交数据,不是幂等,可以对服务器资源造成影响
- PUT:更新资源,幂等,可以对服务器资源造成影响
- DELETE:删除资源,幂等,可以对服务器资源产生影响
- PATCH:局部更新资源,只更新传入的字段,而不是整体的字段
- HEAD:像 GET 一样请求数据,但是没有响应体,只有响应头,可以查看返回的数据的大小之类的元数据
- OPTIONS:用于检查服务器的这个接口支持什么请求方法
HTTP 中 GET 和 POST 的区别是什么?
语义不同:GET 的语义是请求数据,不影响服务器数据,请求一百次还是一样的,POST 的语义是提交数据,服务器会根据数据去更新,每一次都会创建新的记录
参数传递不同:GET 没有请求体,因此会将参数拼接到 URL 上面,大小会被限制,会被日志记录下来,所以敏感信息最好不用 GET 提交,POST 方式有请求体,提交数据一般放在请求体中(虽然也可以放在 URL 中),适合更大的数据,而且不会被日志记录,所以更加安全,但是还是是明文记录的,真安全还是靠 HTTPS
幂等不同:按照规范,GET 请求应该是幂等的,POST 不用做幂等,但是这个规矩是死的,人是活的,具体开发还是看代码怎么写了
缓存机制:因为 GET 是幂等的,浏览器会主动缓存 GET 产生的数据,而 POST 不会去缓存,每次都会去打服务器
HTTP 1.0 和 2.0 有什么区别?
HTTP 作为协议,进化主要有两方面:连接成本,数据冗余
HTTP 1 -> HTTP 1.1:1.0 的链接非常短命,每次请求之后都得断开连接,后续的请求都得重新创建连接,1.1 支持长连接,省去了建立连接的成本,其次,解决了一个服务器只能开放一个网站的问题
HTTP 1.1 -> HTTP 2.0:改变了之前的串行传输模式,防止大任务阻塞后面的小任务,将数据包打散,并行传送,解决了这种问题,然后还取消掉原来的文本编码方式,改为二进制,速度更快,开销小。维护请求头索引表,如果请求头重复,直接发送索引,减少请求头的负载,最后还有个没用的操作,服务器可以预判客户端的请求。直接诶发送数据,避免二次请求
HTTP 2.0 和 3.0 有什么区别?
最大的改动就是由原来的 TCP 传输改成 UTP 传输,真正的实现了并行,也就是说,如果有数据包发送失败了,并不会阻塞全部的数据包,而是会单独补发数据包,减小了网络压力,
HTTP 和 HTTPS 有什么区别?
简单来说就是更安全了
HTTP 数据明文传输,谁都能看,看到了也就意味着能改,HTTPS 有数字加密,只有双端能看到,中间是看不到的
TCP 和 UDP 有什么区别?
TCP 面向链接,发送数据之前需要进行三次捂手,断开连接需要进行四次挥手,建立好链接才发送,保证链接的可靠性,TCP 发送字节流数据,保证顺序,适合对结果有要求的
UDP 面向无连接的,发送数据不需要进行信道的维护,直接将数据以数据报的形式发送,发送数据是无序的,不会保证数据发送成功,适合一些对精度要求不高的场景, 比如游戏,通话等
说说 TCP 的三次握手?
TCP 三次握手就是客户端和服务器通过发送和确认三个包,保证双方的收发能力正常,且同步初始化序列号,并建立可靠连接的过程。
- 第一次握手(客户端 -> 服务端)
客户端发送一个 SYN 报文(SYN=1),并携带一个随机生成的初始化序列号(seq=x)。
此时客户端处于 SYN_SENT(同步已发送)状态。
- 第二次握手(服务端 -> 客户端)
服务端收到 SYN 后,回发一个 SYN+ACK 报文(SYN=1, ACK=1)。确认号是客户端的序列号 + 1(ack=x+1),同时自己也生成一个初始化序列号(seq=y)。
此时服务端处于 SYN_RCVD(同步收到)状态。
- 第三次握手(客户端 -> 服务端)
客户端收到 SYN+ACK 后,发送一个 ACK 报文(ACK=1)。确认号是服务端的序列号 + 1(ack=y+1)。
此时客户端进入 ESTABLISHED(已建立连接)状态。服务端收到 ACK 后,也进入 ESTABLISHED 状态,连接正式建立。
TCP 是用来解决什么问题?
- 在不可靠的互联网上实现可靠的传输
- 实现流量控制和拥堵控制
- 实现流量管理
说说 TCP 的四次挥手?
四次挥手的目的就是为了关闭连接。TCP 作为全双工通信,你不能自己没信息了就关闭信道,得等双方都没信息发送了,再关闭信道
- 第一次挥手:客户端想要关闭会话,自己没消息需要发送了,就发送一个 FIN 告诉服务器,自己没话讲了,停止发送数据,进入 FIN_WAIT_1 状态,服务器收到之后,可以不进行接受数据了,但是得发送没有发送完毕的数据
- 第二次挥手:服务器回复一个 ACK 表示自己知道了,服务器进入 CLOSE_WAIT 阶段,客户端收到之后进入 FIN_WAIT_2 阶段
- 第三次挥手:服务器回复一个 FIN 表示自己没数据了,进行最后的关闭操作,进入 LAST_ACK 阶段
- 第四次挥手:客户端收到 FIN 之后,回复 ACK 然后客户端等待 2MSL,服务器收到 ACK 之后直接关闭
第二次挥手和第三次挥手可以合并,关键点是服务器收到客户端的 FIN 之后能否直接进行关闭,如果有数据就不进行关闭操作,就得分批次发送 ACK 和自己的 FIN,这一前一后就是四次,如果没有数据发送了,就直接合并 FIN 和 ACK 为一次,直接三次解决
TCP 的粘包和拆包能说说吗?
这两个问题产生的主要原因就是 TCP 发送的是字节流,数据之间没有明显的界限,需要交给应用层去分辨
- 黏包:多个数据太小,Nagle 算法将多个数据整合到一起进行发送,节省带宽,或者不经过这个,也会形成黏包
- 拆包:发送缓冲有大小限制,发送的数据可能被自动分片,或者超过 MTU 直接进行分片,造成拆包
解决方法:
- 固定消息大小,不够长补字符,但是有点死板,长了浪费资源,短了不够用
- 分隔符:很简单,消息之间加上特殊的分隔符,通过判断分隔符来判断是否是一个消息,缺点是消息本身得做转义操作,防止消息本身含有字符串
- 效仿 UDP:头部带上数据的大小,直接通过读取头部的信息进行判断数据的大小
UDP 就没有这个问题,UDP 数据包有头,直接记录后面数据的大小,作为一个报文发送,天然带有屏障
说说 TCP 拥塞控制的步骤?
核心目的是通过判断当前 ACK 的数量进行发送速率的约束,大概是这样:
- 链接建立初期,大家都不知道这个网络能跑多少数据,慢慢试,一开始是一个 MSS,每接收到一个 ACK 之后,cwnd 增加 1 个 MSS,因为一个 RTT 能接收到的 ACK 约等于当前的 cwnd,直接进行翻倍了
- TCP 有一个 ssthresh,也就是预设的上限,过了这个上限再指数增长就比较危险了,每个 RTT 只增加一个 MSS,慢慢摸索,探求上限
- 如果连续收到了三个同样的 ACK,可以根据经验,这个包丢了,直接进行重发
- 如果遇到了重传的现象,awnd 减半,将 ssthresh 设为新的 awnd,重新进行线性增长,慢慢探索最大的发送速度
TCP/IP 四层模型是什么?
网络接口层 - 网络层 - 传输层 - 应用层
- 网络接口层:最基础的层级,负责在物理链路上面收发信息,将网络层的 IP 包装配成帧,通过 MAC 寻址
- 网络层:使用 IP 协议在不同的网络中通信,将数据通过路由器送到不同的网络中
- 传输层:传输层使用 TCP UDP 协议负责端对端的进程间的通信,
- 应用层:大部分的协议都放在这,比如 HTTP,FTP,SMTP之类的
Cookie、Session、Token 之间有什么区别?
本质都是为了解决身份管理的问题,
- cookie:服务器发送给客户端的字符串,客户端明文存储,用户请求会将 cookie 带到请求头上,服务器接收到之后解析就知道是哪个用户发来的请求,这个技术让会话有了状态,缺点是明文比较危险
- Session:为了应对 cookie 明文存储的安全问题,可以将用户会话信息存储在服务端,称为 Session,客户端存储 SessionID,会话的时候带上这个 ID,服务器就会进行配对,缺点就是分布式服务器同步 Session 会带来比较大的开销
- Token 又转为了本地存储用户信息,优点是使用了数字签名,不易破解,移动端也能用
从网络角度来看,用户从输入网址到网页显示,期间发生了什么?
- 输入网址:浏览器拿到输入的数据,解析出协议,域名,路径,然后通过域名寻找IP,从本地的浏览器缓存,系统缓存,路由器缓存找,如果都没有,就去 DNS 服务器找,拿到 IP 开始干活
- 拿到 IP 之后就进行三次握手,如果是 HTTPS 就要多一个 TLS 四次握手,保证后续传输安全
- 然后就开始发送数据,数据经过传输层,网络层,数据链路层,分别要加上:TCP 头,IP 头,MAC 头,分别保证其在对应层的传输
- 比如 TCP 头保证进程间的通信,IP 保证网络寻址
- 数据发送后,经过转换,二进制数据被转换成光信号或者电信号被对应的介质发送出去
- 交换机根据数据携带的 MAC 将其转发到不同的接口
- 路由器根据 IP 将其转发到不同的链路,这个时候,路由器会将 MAC 地址换成自己的
- 服务器接到数据之后,开始逐层解包,主要是去除这些协议头的内容,直到最后拿到最后的协议数据
- 服务器响应的数据根据相同的方法返回到客户端的浏览器上被解析出来!
最后更新时间:2026/4/10