计算机网络协议介绍
一、从一个请求来看网络分层原理
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 中的接口,它可以有各种实现方式)。
1.在请求过程中域名是无法直接被计算机识别的,必须先转换成 ip,此时先检测本地是否配置了 host,如果没有配置的话会发起一个 dns 请求。
2.DNS 使用 UDP 作为传输层,DNS 服务器 IP 配置在你的操作系统中,可以直接获取。
3.数据链路层在接收到网络层调用后,会通过 IP 使用 ARP 协议获取当前 IP 对应的 MAC 地址。
4.最终通过物理层将数据传入路由器,路由器进行逆向解析(MAC 地址->IP),如果路由器判断此信息不是给自己的会将信息继续传给下游电信运营商。
5.运营商判断是 DNS 请求还是 HTTP 请求,如果是 DNS 请求会调用 DNS 服务器换取 IP 并返回。
6.获取 IP 后 DNS 请求完成,此时再次发送一次 HTTP 请求,HTTP 在传输层使用的是 TCP 协议,其他层同理。
7.运营商判断如果非 DNS 请求,那么电信会通过运营商直接的协议进行消息的发送,最终找到 ip 对应的服务器。
8.接收端服务器的物理层接受到此次请求,通过对应的协议进行数据的层层解析获取对应的信息,最终将数据传给本地服务器(nginx、tomcat 等),服务器将响应报文通过 HTTP 方式将数据返回。
一次请求的流转如下图:
二、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 表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
•1xx:指示信息–表示请求已接收,继续处理。
•2xx:成功–表示请求已被成功接收、理解、接受。
•3xx:重定向–要完成请求必须进行更进一步的操作。
•4xx:客户端错误–请求有语法错误或请求无法实现。
•5xx:服务器端错误–服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下:
•200 OK:客户端请求成功。
•400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
•401 Unauthorized:请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用。
•403 Forbidden:服务器收到请求,但是拒绝提供服务。
•404 Not Found:请求资源不存在,举个例子:输入了错误的 URL。
•500 Internal Server Error:服务器发生不可预期的错误。
•503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
百度百科 状态码参考网址
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 请求过程描述
1.首先浏览器先解析 URL 中的域名。
2.通过域名获取对应的 ip 地址,上边已经说过 ip 是通过 DNS 服务器获取,我们可以在谷歌浏览器中查看到域名对应 ip 的解析。
3.获取到 IP 地址后,浏览器就可以发起与服务器的三次握手
4.建立连接后,就开始组装 http 请求,发送请求。
5.接收端收到请求后,开始处理请求解析请求头中的数据,并生成对应的响应数据,给发送端返回响应数据。
6.浏览器收到响应后,会通过响应头类型,解析对应的数据报文。
补充:上边 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 三次握手
说明:
1.开始时服务端和客户端的连接处于断开状态。
2.服务端启动后会监听特定端口,处于监听状态,等待客户端的请求。
3.客户端发起请求,变更成发送状态,此时会在请求中携带同步序列号 x。
4.服务端接受到请求后,保存客户端对应的信息,并发送确认收到应答消息,此消息的应答码需要在 x 的基础上加 1,此时服务端处于等待客户端确认状态。
5.客户端收到服务端确认后,状态变更为已连接,客户端也需要给服务端回复确认收到,此时应答码为服务端确认码 y+1。
6.服务端收到客户端确认消息后,状态变更为已连接。
7.连接建立成功,此为三次握手。
8.握手过程中会消耗序号,建立链接后不会消耗。
以下是三次握手的示例过程:
4.5 TCP 四次挥手
说明:
1.客户端和服务端都可以主动发起关闭连接。
2.图中为客户端发起关闭连接,首先客户端发起 FIN 关闭连接请求。
3.服务端收到关闭请求后,先回复收到关闭请求的确认消息给客户端,此时客户端处于等待关闭 2 状态,等待服务端完成收尾工作,服务端完成收尾(剩余未完成传输数据同步),执行关闭连接方法,并给客户端发送 FIN 关闭链接请求。
4.客户端收到关闭请求后,给服务端回复确认关闭应答消息,服务端关闭,客户端处于等待状态,此时需要等待两个最大请求时长(防止服务端由于网络原因未收到应答消息,服务端会重试发送 FIN 消息)。
5.等待时间到期后关闭连接。
4.5 TCP 可靠性传输
4.5.1 停止等待协议
描述:没传送一个报文,服务端都回复一个确认消息,效率低下。
4.5.1 重传机制
4.5.1.1 ack 丢失
描述:如果出现丢包如何处理
4.5.1.2 报文丢失
4.5.2 滑动窗口协议与累计确认(延时 ack)
说明:
1.约定窗口大小为 4,每次发送四个报文。
2.服务端收到后只收到,1,2,4。 3 丢失,此时服务端确认只确认到 2。
3.客户端收到确认后,从 3 开始在滑动下一个窗口,进行数据传输。
参考文献
OSI 参考模型: https://baike.baidu.com/item/OSI参考模型/708028?fr=aladdin
HTTP 状态码: https://baike.baidu.com/item/HTTP状态码?fromModule=lemma_search-box
TCP 协议: https://baike.baidu.com/item/TCP/33012?fr=ge_ala
TCP 与 UDP 的可靠性传输: https://zhuanlan.zhihu.com/p/636141175
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/cd5ad195e982f64609b51b295】。文章转载请联系作者。
评论