+++ title = “httt 协议与 TCP/IP 协议” description = “http 协议和 TCP/IP 协议的理解,以及一些简写的释义。” tags = [‘http’, ‘前端’] date = “2019-09-03” location = “JiNan, CN” type = “post” draft=“true” +++ 参考微信公众号文章,记录一些知识点,原文请点击 👉🏻微信公众号原文

名词缩写释义

OSI 参考模型:OSI 参考模型是一个尝试让全世界计算机互联为网络的概念性框架,为定制标准提供参考的概念性框架。

OSI 参考模型中将计算机网络体系结构划分为 7 层,从下至上依次是:

  • 物理层:光纤和网卡等,负责通信设备和网络媒体之间的互通
  • 数据链路层:以太网,用来加强物理层功能
  • 网络层:IP 协议和 ICMP 协议等,负责数据的路由的选择与数据转寄
  • 传输层:TCP 协议和 UDP 协议等,承上启下,控制连接,控制流量
  • 会话层:建立和维护会话关系
  • 表达层:把数据转换为接受者系统可兼容的格式
  • 应用层:HTTP、FTP、SMTP 和 SSH 等,粗犷的理解为程序员层

TCP/IP 参考模型:TCP/IP 协议代表一整个网络传输协议家族,而不仅仅是 TCP 协议和 IP 协议,TCP 协议和 IP 协议是该协议家族中最早通过的最核心的两个协议标准,因此该协议家族被称作 TCP/IP 协议族,也就是我们通常所说的 TCP/IP 协议。

要完成一个任务需要该协议家族的各种协议分工协作,在该参考模型中的网络体系结构一共分为 4 层,从下至上依次是:

  • 网络连接层:主机与网络相连的协议,如:以太网
  • 网络互联层:IP 协议和 ICMP 协议等,负责数据的路由的选择与数据转寄
  • 传输层:TCP 协议和 UDP 协议等,控制端对端的连接、流量和稳定性
  • 应用层:HTTP、FTP、SMTP 和 SSH 等,粗犷的理解为程序员层

Socket:TCP/IP 协议需要向程序员提供可编程的 API,该 API 就是 Socket

MAC地址: 媒体存取控制位址,也称为局域网地址,它是一个用来确认网络设备位置的位址。在 OSI 模型中,第三层网络层负责 IP 地址,第二层数据链路层则负责 MAC 位址。

ARP:地址解析协议,即 ARP(Address Resolution Protocol),是根据 IP 地址获取物理地址的一个 TCP/IP 协议。

TCP 的数据结构图

  • SYN:建立连接标识
  • ACK:响应标识
  • FIN:断开连接标识
  • seq:seq number,发送序号
  • ack:ack number,响应序号

建立 TCP 连接,3 次握手

  • 客户端发送 SYN, seq=x,进入 SYN_SEND 状态
  • 服务端回应 SYN, ACK, seq=y, ack=x+1,进入 SYN_RCVD 状态
  • 客户端回应 ACK, seq=x+1, ack=y+1,进入 ESTABLISHED 状态,服务端收到后进入 ESTABLISHED 状态

进行数据传输

  • 客户端发送 ACK, seq=x+1, ack=y+1, len=m
  • 服务端回应 ACK, seq=y+1, ack=x+m+1, len=n
  • 客户端回应 ACK, seq=x+m+1, ack=y+n+1

断开 TCP 连接, 4 次挥手

  • 主机 A 发送 FIN, ACK, seq=x+m+1, ack=y+n+1,进入 FNIWAIT1 状态
  • 主机 B 回应 ACK, seq=y+n+1, ack=x+m+1,进入 CLOSEWAIT 状态,主机 A 收到后 进入 FINWAIT_2 状态
  • 主机 B 发送 FIN, ACK, seq=y+n+1, ack=x+m+1,进入 LAST_ACK 状态
  • 主机 A 回应 ACk, seq=x+m+1, ack=y+n+1,进入 TIME_WAIT 状态,等待主机 B 可能要求重传 ACK 包,主机 B 收到后关闭连接,进入 CLOSED 状态或者要求主机 A 重传 ACK,客户端在一定的时间内没收到主机 B 重传 ACK 包的要求后,断开连接进入 CLOSED 状态

根据 HTTP 协议,更加规范的来看包体的内容类型可以分为三大类,分别是 URL 参数、任意流和表单。

  • 第一种,发送 URL 参数,在 Body 中的数据是这样拼接的:
name=harry&gender=man

此时,请求头Content-Type是:

Content-Type: application/x-www-form-urlencoded
  • 第二种,任意流,可以是字节流、字符流或者文件流等。

例一:json等特定格式数据

{ "name": "harry", "gender": "man" }

此时,请求头Content-Type是:

Content-Type: application/json

例二,发送任意字符串数据,在 Body 中数据是这样的:eg:‘hello world’

此时,请求头Content-Type是:

Content-Type: text/plain

例三,发送已知类型的文件,比如是一张jpeg的图片

此时,请求头Content-Type是对应的文件的MimeType:

Content-Type: image/jpeg

例四,未知类型的数据或者文件,此时 Body 中可以想象成这样:

此时,请求头Content-Type是:

Content-Type: application/octet-stream
  • 第三种,表单数据,因为表单具有一定的格式,所以只要按照格式上传就可以传递复杂的数据,比如可以在表单中全部传递字符串,也可以全部是文件,也可以是文件和字符串的混合,表单实际上可以理解为一个对象键值对,下面是表单的数据结构:

此时,请求头Content-Type是: 参考

Content-Type: multipart/form-data; boundary={boundary}

后边就懵了。。。