一、从一个请求来看网络分层原理
1.1 复杂的网络
以下为一次请求过程中可能遇到的问题,预示着网络的复杂性。

1.2 如何简化复杂度
为了简化网络的复杂度,网络通信的不同方面被分解为多层次结构,每一层只与紧挨着的上层或者下层进行交互,将网络分层,这样就可以修改,甚至替换某一层的软件,只要层与层之间的接口保持不变,就不会影响到其他层。
1.2.1 OSI( Open System Interconnection Reference Model): 开放系统互联参考模型


1.2.2 TCP/IP 协议族

1.2.3 两种协议的对应关系
应用层:应用程序负责的部分
传输层:TCP、UDP、SCTP 等
网络层:IPv4、IPv6等
数据链路层:以太网、无限LAN(WIFI)
物理层:光纤、双绞线电缆、无线设备

1.3 一个请求的分层解析流程
请求各层之间都是调用对应层的接口(这个接口可以类比java中的接口,它可以有各种实现方式)。
一次请求的流转如下图:

二、HTTP协议
超文本传输协议(HyperText Transfer Protocol,HTTP): 一种无状态的,以请求/应答方式运行的协议,它使用可扩展的语义和自描述消息格式,与 基于网络的超文本信息系统灵活的互动
2.1 HTTP报文格式
请求报文和响应报文的结构基本相同。
起始行:描述请求或响应的基本信息。
头部字段集合:key-value结构,报文的详细信息。
消息体:真实传输的内容,可以是文本或二进制等。
2.1.1 HTTP请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,下图给出了请求报文的一般格式。

2.1.1.1 请求行
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
2.1.1.2 请求头部
请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
User-Agent:产生请求的浏览器类型。 Accept:客户端可识别的内容类型列表。 Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
2.1.1.3 空行
最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
2.1.1.4 请求数据
请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type(这个主体的对象类型)和Content-Length(主体的长度)。
2.1.1.5 头部字段注意事项
字段名不区分大小写,字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线“_”(有的服务器不会解析带“_”的头字段)。字段名后面必须紧接着“:”,不能有空格,而“:”后的字段值前可以有多个空格; 字段的顺序是没有意义的,可以任意排列不影响语义; 字段原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie。
2.1.2 HTTP响应报文
HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文。

2.1.2.1 状态行格式如下
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
常见状态代码、状态描述的说明如下:
百度百科 状态码参考网址
2.1.2.1 响应头
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:Date,X-API-Request-Id
Content-Encoding:gzip
Content-Type:application/json;charset=UTF-8
Date:Sun, 10 Mar 2024 12:00:17 GMT
2.1.2.2 响应实体内容
服务器发给浏览器,要让浏览器显示的内容(html,js,css,图片,数据等信息)。
三、HTTP请求完整过程
3.1 请求过程描述
补充:上边2中从浏览器中获取域名的步骤。
浏览器中输入:chrome://net-export/
打开对应文件搜索你想找的域名即可。

四、TCP协议
4.1 TCP协议描述
面向连接的,可靠的,基于字节流的传输层通信协议
4.2 TCP协议特点
4.3 TCP连接管理
4.3.1 TCP连接四元组
四元组分别为:源地址、 源端口、 目的地址、 目的端口
4.3.2 TCP头部格式

序列号:在建⽴连接时由计算机⽣成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送⼀次数据,就累加⼀次该数据字节数的⼤⼩。⽤来解决⽹络包乱序问题。
确认应答号:指下⼀次期望收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。⽤来解决不丢包的问题。
控制位:
ACK:该位为 1 时,确认应答的字段变为有效,TCP 规定除了最初建⽴连接时的 SYN 包之外该位必须设置为 1 。
RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
SYN:该位为 1 时,表示希望建⽴连接,并在其序列号的字段进⾏序列号初始值的设定。
FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双⽅的 主机之间就可以相互交换FIN位为 的 TCP 段。
URG:当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应该尽快传送,而不按照原来的排队序列来传送。
PSH:推送(PuSH),当两个应用进程进行交互式的通信时,有时一端的应用进程希望在键入一个命令之后就能立即收到对方的响应。在这样的情况下,就可以使用推送操作,此时,发送方将PSH置为1,并创建一个报文发送出去,接收端接受到该报文,发现PSH为1,就尽快交付接受应用进程,而不用等到整个缓存都满了之后再向上交付。
紧急数据指针:当发送端需要发送一些紧急数据时,可以设置紧急指针来指示接收端,在接收到该指针之后尽快处理这些数据。紧急指针的值是一个相对于当前序列号的偏移量,用于指示紧急数据在整个数据流中的位置。
窗口大小:当前服务器缓存可接受的数据报文大小。
4.4 TCP 三次握手

说明:
以下是三次握手的示例过程:

4.5 TCP 四次挥手

说明:
4.5 TCP 可靠性传输
4.5.1 停止等待协议
描述:没传送一个报文,服务端都回复一个确认消息,效率低下。

4.5.1 重传机制
4.5.1.1 ack丢失
描述:如果出现丢包如何处理

4.5.1.2 报文丢失

4.5.2 滑动窗口协议与累计确认(延时ack)

说明:
参考文献
OSI参考模型: https://baike.baidu.com/item/OSI%E5%8F%82%E8%80%83%E6%A8%A1%E5%9E%8B/708028?fr=aladdin
HTTP状态码: https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81?fromModule=lemma_search-box
TCP协议: https://baike.baidu.com/item/TCP/33012?fr=ge_ala
TCP与UDP的可靠性传输: https://zhuanlan.zhihu.com/p/636141175