计算机网络笔记

网络

本文大量引用自 http://www.iocoder.cn/

目录
  • 网络
    • BS结构中的协议
    • OSI 七层体系结构
    • TCP/IP
    • 各个层使用的是哪个数据交换设备?
      • 网关:应用层、传输层。
      • 路由器:网络层
      • 交换机:数据链路层、网络层
      • 网桥:数据链路层
      • 集线器(Hub):物理层
      • 中继器:物理层
    • IP
      • IP 地址的分类?
        • 子网掩码的作用?
        • IP 地址与物理地址的区别?
        • 网络层的 ARP 协议工作原理
      • 如何划分子网、超网?
        • 如何划分子网?
        • 如何划分超网?
      • 什么是单播、组播(多播)、广播、任播?
      • 区别 IPv4 和 IPv6 ?
    • ICMP
      • ICMP 协议的主要功能
      • 简述一下 ping 的原理?
      • 什么是 Traceroute ?
    • TCP
      • TCP 是什么?
      • TCP 对应的应用层协议
      • TCP 头部是怎么样的?
      • TCP三次握手
        • 为什么 TCP 连接需要三次握手,两次不可以么,为什么?
        • 客户端不断进行请求链接会怎样?
        • 如何检测 SYN 攻击?
        • 怎么解决 SYN 攻击呢?
      • TCP 四次挥手
        • 为什么要四次挥手?
        • TIME_WAIT和CLOSE_WAIT状态区别
      • TCP 数据如何传输?
        • TCP 数据传输丢失怎么办?什么是 TCP 重传?
      • TCP滑动窗口
      • TCP 协议如何来保证传输的可靠性?
      • TCP 拥堵
        • 怎么解决 TCP 拥堵?
    • UDP
      • UDP是什么
      • UDP 对应的应用层协议?
      • TCP 与 UDP 的区别
        • 为什么 TCP 叫数据流模式? UDP 叫数据报模式?
      • UDP 报文的格式
    • DNS
      • DNS 是什么?
      • 主机解析域名的顺序?
      • DNS 使用什么协议?
    • HTTP
      • HTTP的作用
      • HTTP协议组成
        • 请求协议信息
          • HTTP 协议包括哪些请求?
          • GET 和 POST 的区别
        • 响应协议信息
          • URI 和 URL的区别
          • HTTP 有哪些状态码?
      • HTTP协议版本
        • 现在有哪些版本:
        • HTTP1.1和HTTP1.0的区别:
      • 一次完整的 HTTP 请求所经历的步骤
    • HTTPS(todo)
      • 什么是 HTTPS
      • HTTP 和 HTTPS 的区别
      • 什么是 SSL/ TLS
      • SSL/TLS 协议作用
      • SSL 加密方式
        • 为什么公钥传输的步骤这么复杂呢?
      • 什么是单向认证、双向认证?
        • 单向认证的过程
        • 双向认证的过程
        • 如何选择单向认证还是双向认证
      • 为什么抓包工具还能抓到 HTTPS 数据包并解密成功呢
      • HTTPS 握手会影响性能么?
    • HTTP 2.0
      • HTTP 2.0是什么?
        • SPDY是什么?
      • HTTP2.0 和 HTTP1.X 相比的新特性
      • HTTP2.0 的多路复用和 HTTP1.X 中的长连接复用的区别
        • HTTP2.0 多路复用有多好?
      • 为什么需要头部(header)压缩?
      • 服务器推送是什么?
      • HTTP、TCP、Socket 的关系是什么?

互联网是一个错综复杂的网络,其中包含的节点不计其数,而且每两个节点之间的距离以及连接的路线都是不确定的,数据在传输的过程中还可能会丢失。将复杂问题进行分治,将其分解成多个简单问题,然后通过解决每个简单问题,最终解决复杂问题。

BS结构中的协议

  在BS结构中,首先使用到DNS协议;网络传输部分使用TCP/IP参考模型,其中网络接入层没有相应协议,网际互联层是IP协议,传输层是TCP协议,应用层是HTTP协议 (TCP/IP协议并不能具体工作,就像是程序中的接口,而Socket是TCP/IP协议的一个具体实现);另外在HTTP协议的上层还有Servlet标准。

BS结构网络传输的分解方式有两种:一种是标准的OSI参考模型,另一种是TCP/IP参考模型。

OSI和TCP/IP分层模型及对应关系如图所示。
计算机网络笔记_第1张图片

OSI 七层体系结构

  • 应用层(数据):确定进程之间通信的性质以满足用户需要以及提供网络与用户应用
  • 表示层(数据):主要解决用户信息的语法表示问题,如加密解密
  • 会话层(数据):提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制,如服务器验证用户登录便是由会话层完成的
  • 传输层(段):实现网络不同主机上用户进程之间的数据通信,可靠
    与不可靠的传输,传输层的错误检测,流量控制等
  • 网络层(包):提供逻辑地址(IP)、选路,数据从源端到目的端的
    传输
  • 数据链路层(帧):将上层数据封装成帧,用MAC地址访问媒介,错误检测与修正
  • 物理层(比特流):设备之间比特流的传输,物理接口,电气特性等

TCP/IP

TCP/IP 是Internet上的标准通信协议集,该协议集由数十个具有层次结构的协议组成,其中TCP和IP是该协议集中的两个最重要的核心协议。TCP/IP协议族按层次可分为以下四层:应用层、传输层、网络层和网络接口层,各层对应的PDU数据单元的名称如下图所示。
计算机网络笔记_第2张图片

  • 应用层:使用接收到的数据
  • 传输层:实际传输数据
  • 国际互联网:找到要传输数据的目标节点
  • 网络接入层:将需要相互连接的节点接入网络中,从而为数据传输提供条件

这种分层理念是比较容易理解的,比如我们网上购物,首先确定自己的收货地点有相应的快递,就相当于网络接入层;然后告诉卖家地址,就类似于国际互联层;快递传输就相当于传输层;最后我们接受快递拆包使用,就是应用层。

《看透springMVC源码分析与实践》

各个层使用的是哪个数据交换设备?

网关:应用层、传输层。

网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。

网关的结构也和路由器类似,不同的是互连层。网关既可以用于广域网互连,也可以用于局域网互连

路由器:网络层

路由选择、存储转发。

交换机:数据链路层、网络层

识别数据包中的 MAC 地址信息,根据 MAC 地址进行转发,并将这些 MAC 地址与对应的端口记录在自己内部的一个地址表中。

网桥:数据链路层

将两个 LAN 连起来,根据 MAC 地址来转发帧。

集线器(Hub):物理层

纯硬件设备,主要用来连接计算机等网络终端。

中继器:物理层

在比特级别对网络信号进行再生和重定时,从而使得它们能够在网络上传输更长的距离。

IP

IP 地址的分类?

IP 地址是指互联网协议地址,是 IP 协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

IP 地址编址方案将IP地址空间划分为 A、B、C、D、E 五类,其中 A、B、C 是基本类,D、E 类作为多播和保留使用,为特殊地址。

每个 IP 地址包括两个标识码(ID),即网络 ID 和主机 ID 。同一个物理网络上的所有主机都使用同一个网络 ID ,网络上的一个主机(包括网络上工作站,服务器和路由器等)有一个主机 ID 与其对应。A~E 类地址的特点如下:

计算机网络笔记_第3张图片
计算机网络笔记_第4张图片

  • A 类地址:以 0 开头,第一个字节范围:0~127 。一般用于大型网络。
    地址范围:1.0.0.1-126.255.255.254 (0000 0001.00000000.00000000.00000000~01111110.111111111.11111111.11111110)
    地址范围:1.0.0.0-126.255.255.255 (这种写法是把全0全1都算进去了,其它几类类似)
    网络号范围: 1~126 (0000 0001 ~ 0111 1110)
    默认子网掩码:255.0.0.0 或 0xFF000000(十六进制)
    私有号段:10.0.0.0-10.255.255.255
    最大网络数:2^7 - 2 = 126
    最大主机数:2^24 - 2(全0全1的地址不可分配,作为保留地址,所以-2)

    回送地址:

    127.x.x.x 有的资料说,它属于A类。

    如127.0.0.1 等效于localhost本机IP。 一般用于测试使用。

    例如:ping 127.0.0.1来测试本机TCP/IP是否正常。http://127.0.0.1:8080 等效 http://localhost:8080

  • B 类地址:以 10 开头,第一个字节范围:128~191 。一般用于中等规模网络。
    地址范围:128.1.0.1-191.255.255.254
    网络号范围:128.1 ~ 191.255 (可用范围)
    默认子网掩码:255.255.0.0 或 0xFFFF0000(十六进制)
    私有号段:172.16.0.0-172.31.255.255
    最大网络数:2^14 - 1
    最大主机数:2^16 - 2(全0全1的地址不可分配,作为保留地址,所以-2)

  • C 类地址:以 110 开头,第一个字节范围:192~223。一般用于小型网络。

    地址范围:192.0.1.1-223.255.255.254
    网络号段范围:192.0.1 ~ 223.255.255
    子网掩码:255.255.255.0 或 0xFFFFFF00 (十六进制)
    私有号段:192.168.0.0-192.168.255.255

    最大网络数:2^21 - 1
    最大主机数:2^8 - 2(全0全1的地址不可分配,作为保留地址,所以-2)

  • D 类地址:以 1110 开头,第一个字节范围:224~239 。一般用于多路广播用户 。
    地址范围:224.0.0.1-239.255.255.254
    是多播地址。该类IP地址的最前面为“1110”,所以地址的网络号取值于224~239之间。

  • E 类地址:以 1111 开头,保留地址。
    该类IP地址的最前面为“1111”,所以地址的网络号取值于240~255之间。

子网掩码的作用?

​ 子网掩码只有一个作用,就是将某个 IP 地址划分成网络地址主机地址两部分。

​ 用于子网掩码的位数,决定于可能的子网数目和每个子网的主机数目。

IP 地址与物理地址的区别?
  • 物理地址(MAC 地址),是数据链路层和物理层使用的地址。
  • IP 地址是网络层和以上各层使用的地址,是一种逻辑地址。
  • 其中 ARP 协议用于 IP 地址与物理地址的对应。

详细的,可以看看 《即生瑜,何生亮 —— MAC 地址与 IP 地址》 文章。

网络层的 ARP 协议工作原理

网络层的 ARP 协议完成了 IP 地址与物理地址的映射

  • 首先,每台主机都会在自己的 ARP 缓冲区中建立一个 ARP 列表,以表示 IP 地址和 MAC 地址的对应关系。
  • 当源主机需要将一个数据包要发送到目的主机时,会首先检查自己 ARP 列表中是否存在该 IP 地址对应的 MAC 地址:
    • 如果有,就直接将数据包发送到这个 MAC 地址。
    • 如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的 MAC 地址。此 ARP 请求数据包里包括源主机的 IP 地址、硬件地址、以及目的主机的 IP 地址。网络中所有的主机收到这个 ARP 请求后,会检查数据包中的目的 IP 是否和自己的 IP地址一致。
      • 如果不相同,就忽略此数据包。
      • 如果相同,该主机首先将发送端的 MAC 地址和 IP 地址添加到自己的 ARP 列表中(如果 ARP 表中已经存在该 IP 的信息,则将其覆盖),然后给源主机发送一个 ARP 响应数据包,告诉对方自己是它需要查找的 MAC 地址。
        • 源主机收到这个 ARP 响应数据包后,将得到的目的主机的 IP 地址和 MAC 地址添加到自己的 ARP 列表中,并利用此信息开始数据的传输。
        • 如果源主机一直没有收到 ARP 响应数据包,表示 ARP 查询失败。

注意,在 OSI 模型中 ARP 协议属于链路层;而在 TCP/IP 模型中,ARP 协议属于网络层。

如何划分子网、超网?

如何划分子网?

划分子网(变长子网掩码 VLSM):划分子网的方法是从网络的主机号借用若干位作为子网号 subnet-id ,与此同时主机号也减少相应位数(总位数 32 位不变)。

由此两级 IP 地址可变为三级 IP 地址:IP地址 ::= {<网络号>,<子网号>,<主机号>}划分子网只是把 IP 地址的主机号这部分进行再划分,并不改变 IP 地址原来的网络号。

如何划分超网?

构造超网(无分类编址 CIDR):CIDR 消除了传统的 A 类、B 类和 C 类地址以及划分子网的概念,把 32 位的 IP 地址划分为两个部分。

例如:128.14.35.7/20 是某个 CIDR 地址块中的一个地址,其前 20 位是网络前缀(用下划线表示的部分),后面的 12 位为主机号。

什么是单播、组播(多播)、广播、任播?

  • 单播(unicast): 是指封包在计算机网络的传输中,目的地址为单一目标的一种传输方式。它是现今网络应用最为广泛,通常所使用的网络协议或服务大多采用单播传输,例如一切基于TCP的协议。
  • 组播(multicast): 也叫多播, 多点广播或群播。 指把信息同时传递给一组目的地址。它使用策略是最高效的,因为消息在每条网络链路上只需传递一次,而且只有在链路分叉的时候,消息才会被复制。
  • 广播(broadcast):是指封包在计算机网络中传输时,目的地址为网络中所有设备的一种传输方式。实际上,这里所说的“所有设备”也是限定在一个范围之中,称为“广播域”。
  • 任播(anycast):是一种网络寻址和路由的策略,使得资料可以根据路由拓朴来决定送到“最近”或“最好”的目的地。

区别 IPv4 和 IPv6 ?

  • 我们大多数人使用的是第二代互联网 IPv4 技术,它的最大问题是网络地址资源有限,从理论上讲能编址 1600 万个网络、链接 40 亿台主机。而根据相关数据,全球 IPv4 的 IP 地址已经即将用完。
  • 而 IPv6 是作为 IETF 设计的用于替代现行版本 IP 协议(IPv4)的下一代 IP 协议,其 IPV6 地址长度为 128位,地址空间增大了 2^98 次方倍,几乎可以说是用之不竭的。所以随着 IPv4 不足,支持 IPv6 的网络势必会增长。

ICMP

ICMP 协议的主要功能

用于在 IP 主机、路由器之间传递控制消息。
计算机网络笔记_第5张图片

简述一下 ping 的原理?

一般在网络不通的时候,大家会用 ping 测一下网络是否通畅。

ping 是基于 ICMP 协议工作的。ICMP 全称 Internet Control Message Protocol ,就是互联网控制报文协议。这里的关键词是“控制”,那具体是怎么控制的呢? 网络包在异常负责的网络环境中传输时,会遇到各种问题,当遇到问题时,要传出消息,报告情况,这样才能调整传输策略。

ICMP 报文是封装在 IP 包里面的。因为传输指令的时候,肯定需要源地址和目标地址。如下图:
计算机网络笔记_第6张图片

什么是 Traceroute ?

Traceroute ,构建在 ICMP 协议之上的应用。是用来侦测主机到目的主机之间所经路由情况的重要工具,也是最便利的工具。

前面说到,尽管 ping 工具也可以进行侦测,但是,因为 IP 头的限制,ping 不能完全的记录下所经过的路由器。所以Traceroute 正好就填补了这个缺憾。

Traceroute 的原理是非常非常的有意思。

  • 它受到目的主机的 IP 后,首先给目的主机发送一个 TTL=1的 UDP(后面就知道 UDP是什么了)数据包,而经过的第一个路由器收到这个数据包以后,就自动把 TTL 减1,而 TTL 变为 0 以后,路由器就把这个包给抛弃了,并同时产生 一个主机不可达的 ICMP 数据报给主机。

    (在IPv4包头中TTL是一个8 bit字段。作用是限制IP数据包在计算机网络中的存在的时间。)

  • 主机收到这个数据报以后再发一个 TTL=2 的 UDP 数据报给目的主机,然后刺激第二个路由器给主机发 ICMP 数据 报。如此往复直到到达目的主机。

这样,traceroute 就拿到了所有的路由器 IP 。从而避开了 IP 头只能记录有限路由 IP 的问题。

有人要问,我怎么知道 UDP 到没到达目的主机呢?

这就涉及一个技巧的问题,TCP 和 UDP 协议有一个端口号定义,而普通的网络程序只监控少数的几个号码较小的端口,比如说 80、23 等等。而 traceroute 发送的是端口号 >30000(真变态) 的 UDP 包,所以到达目的主机的时候,目的主机只能发送一个端口不可达的 ICMP 数据报给主机。主机接到这个报告以后就知道,目标主机到了。

很多情况下,在我们 ping 不通目标地址时,会尝试使用 traceroute 命令,看看是否在中间哪个 IP 无法访问。

TCP

TCP 是什么?

TCP(Transmission Control Protocol),传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。主要特点如下:

  • TCP 是面向连接的。

    就好像打电话一样,通话前需要先拨号建立连接,通话结束后要挂机释放连接

  • 每一条 TCP 连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)。

  • TCP 提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达。

  • TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双方通信的数据。

  • 面向字节流。

    TCP 中的“流”(Stream),指的是流入进程或从进程流出的字节序列。

    “面向字节流”的含义是:虽然应用程序和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。

TCP 对应的应用层协议

  • FTP :定义了文件传输协议,使用 21 端口。常说某某计算机开了 FTP 服务便是启动了文件传输服务。下载文件,上传主页,都要用到 FTP 服务。
  • Telnet :它是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于 DOS 模式下的通信服务。如以前的 BBS 是纯字符界面的,支持 BBS 的服务器将 23 端口打开,对外提供服务。
  • 邮箱
    • SMTP :定义了简单邮件传送协议,现在很多邮件服务器都用的是这个协议,用于发送邮件。如常见的免费邮件服务中用的就是这个邮件服务端口,所以在电子邮件设置-中常看到有这么 SMTP 端口设置这个栏,服务器开放的是 25 号端口。
    • POP3 :它是和 SMTP 对应,POP3 用于接收邮件。通常情况下,POP3 协议所用的是 110 端口。也是说,只要你有相应的使用 POP3 协议的程序(例如 Foxmail 或 Outlook),就可以不以 Web 方式登陆进邮箱界面,直接用邮件程序就可以收到邮件(如是 163 邮箱就没有必要先进入网易网站,再进入自己的邮箱来收信)。
  • HTTP :从 Web 服务器传输超文本到本地浏览器的传送协议。

TCP 头部是怎么样的?

计算机网络笔记_第7张图片
计算机网络笔记_第8张图片

上面就是TCP协议头部的格式,由于它太重要了,是理解其它内容的基础,下面就将每个字段的信息都详细的说明一下。

  • Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接;
  • Sequence Number:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题;
  • Acknowledgment Number:32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题;
  • Offset:给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;
  • TCP Flags:TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为URG,ACK,PSH,RST,SYN,FIN。每个标志位的意思如下:

URG:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;

ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;

PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;

RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;

SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手;

FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。

  • Window:窗口大小,也就是有名的滑动窗口,用来进行流量控制;这是一个复杂的问题,这篇博文中并不会进行总结的;

TCP三次握手

三次握手,简单来说,就是:

  • 发送方:我要和你建立链接?
  • 接收方:你真的要和我建立链接么?
  • 发送方:我真的要和你建立链接,成功。

详细来说,步骤如下:

TCP中的两个序号和三个标志位的含义:
seq(sequence number):表示所传数据的序号。TCP传输时每一个字节都有一个序号,发送数据时会将数据的第一个序号发送给对方,接收方会按序号检查是否接收完整了,如果没接收完整就需要重新传送,这样就可以保证数据的完整性。
ack(acknoledgement number):表示确认号。接收端用它来给发送端反馈已经成功接收到数据,它的值为希望接收的下一个数据包起始序号。

ACK:确认位,只有ACK=1的时候ack才起作用。正常通信时ACK为1,第一次发起请求时因为没有需要确认接收的数据所以ACK为0。

SYN:同步位,用于在建立连接时同步序号。刚开始建立连接时并没有历史接收的数据,所以ack也就没办法设置,这时按照正常的机制就无法运行了,SYN的作用就是来解决这个问题的,当接收端接收到SYN=1的报文时就会直接将ack设置为接收到的seq+1的值,注意这里的值并不是校验后设置的,而是根据SYN直接设置的,这样正常的机制就可以运行了,所以SYN叫同步位。需要注意的是,SYN会在前两次握手时都为1,这是因为通信的双方的ack都需要设置一个初始值。
FIN:终止位,用来在数据传输完毕后释放连接。
计算机网络笔记_第9张图片

  • 第一次握手:Client 将标志位 SYN=1,随机产生一个值 seq=x (x一般为1),第一次发起请求时因为没有需要确认接收的数据所以ACK = 0。并将该数据包发送给 Server 。
    此时,Client 进入SYN_SENT 状态,等待 Server 确认。
  • 第二次握手:Server 收到数据包后由标志位 SYN=1 知道Client请求建立连接,
    Server 将标志位SYN=1ACK=1ack=x+1,随机产生一个值 seq=y,并将该数据包发送给 Client 以确认连接请求。
    此时,Server 进入 SYN_RCVD 状态。
  • 第三次握手:Client 收到确认后,检查ack是否为x+1,ACK是否为 1 。明确从客户端到服务器的数据传输是否是正常的。
    • 如果正确,则将标志位ACK=1ack=y+1,并将该数据包发送给 Server 。此时,Client 进入 ESTABLISHED 状态。明确了从客户端到服务器的数据传输是正常的。
    • Server 检查 ack 是否为 y+1ACK 是否为 1 ,如果正确则连接建立成功。此时 Server 进入 ESTABLISHED 状态,完成三次握手,随后 Client 与 Server 之间可以开始传输数据了。

仔细看来,Client 会发起两次数据包,分别是 SYNC 和 ACK;

​ Server 会发起一次数据包,包含 SYNC 和 ACK 。

​ 也就是说,三次握手的过程中,Client 和 Server 互相做了一次 SYNC 和 ACK。

三次握手中前两次可以保证服务端可以正确接收并返回请求,后两次可以保证客户端可以正确接收并返回请求。

为什么 TCP 连接需要三次握手,两次不可以么,为什么?

为了防止已失效的连接请求报文突然又传送到了服务端,因而产生错误,建立了多余的链接,防止了服务器端的一直等待而浪费资源

客户端发出的连接请求报文并未丢失,而是在某个网络节点长时间滞留了,以致延误到链接释放以后的某个时间才到达 Server 。

  • 若不采用“三次握手”,那么只要 Server 发出确认数据包,新的连接就建立了。由于 Client 此时并未发出建立连接的请求,所以其不会理睬 Server 的确认,也不与 Server 通信;而这时 Server 一直在等待 Client 的请求,这样 Server 就白白浪费了一定的资源。
  • 若采用“三次握手”,在这种情况下,由于 Server 端没有收到来自客户端的确认,则就会知道 Client 并没有要求建立请求,就不会建立连接。

引用知乎上的别人引用的一个回答,从另外一个角度阐释:

在Google Groups的TopLanguage中看到一帖讨论TCP“三次握手”觉得很有意思。贴主提出“TCP建立连接为什么是三次握手?”的问题,在众多回复中,有一条回复写道:“这个问题的本质是,信道不可靠, 但是通信双发需要就某个问题达成一致。而要解决这个问题,,无论你在消息中包含什么信息, 三次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的。请注意这里的本质需求,信道不可靠,数据传输要可靠。三次达到了,那后面你想接着握手也好,发数据也好,跟进行可靠信息传输的需求就没关系了。因此,如果信道是可靠的,即无论什么时候发出消息,对方一定能收到,或者你不关心是否要保证对方收到你的消息,那就能像UDP那样直接发送消息就可以了”。这可视为对“三次握手”目的的另一种解答思路。

客户端不断进行请求链接会怎样?

服务器端准备为每个请求创建一个链接,并向其发送确认报文,然后等待客户端进行确认后创建。如果此时客户端发出第一次握手(并接到第二次握手)后就不回应第三次握手了,这时服务端会以为是第二次握手的数据在传输过程中丢失了,然后重新发送第二次握手,默认情况下会一直发送五次,如果发送五次后还收不到第三次握手则会丢弃请求,如果是个别这种请求当然也没什么关系,可凡事就怕一个多字,当有大量这种请求时就麻烦了,这时服务器就会浪费大量的资源甚至可能导致无法处理正常的请求,这就是DDOS攻击中的SYN Flood攻击。

如何检测 SYN 攻击?

检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源 IP 地址是随机的,基本上可以断定这是一次 SYN 攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

怎么解决 SYN 攻击呢?

答案是只能预防,没有彻底根治的办法,除非不使用 TCP 。方式如下:

  1. 限制同时打开 SYN 半链接的数目

  2. 缩短 SYN 半链接的 Timeout 时间

  3. 关闭不必要的服务。使得这个服务就不会被 SYN 攻击连接。

  4. 增加最大半连接数。

  5. 过滤网关防护。

  6. SYN cookie技术。

  7. 设置第二次请求的重发次数(tcp_synack_retries),不过重发的次数太小也可能导致正常的请求中因为网络没有收到第二次握手而连接失败的情况,具体设置为多少合适,还需要根据实际情况判断。

TCP 四次挥手

四次挥手,简单来说,就是:

  • 发送方:我要和你断开连接!
  • 接收方:好的,断吧。
  • 接收方:我也要和你断开连接!
  • 发送方:好的,断吧。

详细来说,步骤如下:
计算机网络笔记_第10张图片

使用 Client 和 Server 的方式,仅仅是为了方便,也是可以从 Server 向 Client 发起。

  • 第一次挥手:Client 发送一个 FIN ,seq=u,用来关闭 Client 到 Server 的数据传送。

    此时,Client 进入 FIN_WAIT_1 状态,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。

    注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。

  • 第二次挥手,Server 收到 FIN后,发送一个 ACK给 Client ,确认号ack=u+1(与 SYN 相同,一个 FIN占用一个序号)。seq=b

    此时,Server 进入 CLOSE_WAIT 状态。TCP 链接处于半关闭状态。

  • 第三次挥手,服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备。

    Server向客户端发出一段TCP报文,标记位为FINACK,表示“已经准备好释放连接了”。seq=w。确认号为ack=u+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号ack的值。

    注意:这里的ACK并不是确认收到服务器端报文的确认报文。

    此时 Server 进入 LAST_ACK 状态。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。

  • 第四次挥手,Client 收到 FIN 后,此时 Client 进入 TIME_WAIT 状态。接着,Client 发送一个 ACK 给 Server ,确认号ack为 w+1

    Server 接收到后,此时 Server 进入 CLOSED 状态,完成四次挥手。

为什么要四次挥手?

TCP 协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP 是全双工模式,这就意味着:

  • 当主机 1 发出 FIN 报文段时,只是表示主机 1 已经没有数据要发送了,主机 1 告诉主机 2 ,它的数据已经全部发送完毕了;但是,这个时候主机 1 还是可以接受来自主机 2 的数据;当主机 2 返回 ACK 报文段时,表示它已经知道主机 1 没有数据发送了,但是主机 2 还是可以发送数据到主机 1 的。

    因为主机 2 此时可能还有数据想要发送给主机 1 ,所以挥手不能像握手只有三次,而是多了那么“一次”!

  • 当主机 2 也发送了 FIN 报文段时,这个时候就表示主机 2 也没有数据要发送了,就会告诉主机 1 ,我也没有数据要发送了,之后彼此就会愉快的中断这次 TCP 连接。

如果要正确的理解四次的原理,就需要了解四次挥手过程中的状态变化。

主动方=发送方;被动方=接收方。

状态前面的(主动方)(被动方),表示该状态属于谁。

  • (主动方)FIN_WAIT_1 :这个状态要好好解释一下,其实 FIN_WAIT_1 和 FIN_WAIT_2 状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:

    • FIN_WAIT_1 状态实际上是当 Socket 在 ESTABLISHED 状态时,它想主动关闭连接,向对方发送了 FIN 报文,此时该 Socket 即进入到 FIN_WAIT_1 状态。
    • 而当对方回应 ACK报文后,则进入到 FIN_WAIT_2 状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK 报文。所以, FIN_WAIT_1 状态一般是比较难见到的,而 FIN_WAIT_2 状态还有时常常可以用 netstat 看到。
  • (主动方)FIN_WAIT_2 :上面已经详细解释了这种状态,实际上 FIN_WAIT_2 状态下的 Socket,表示半连接,也即有一方要求 close 连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK 信息),稍后再关闭连接。

  • (被动方)CLOSE_WAIT :这种状态的含义其实是表示在等待关闭。

    怎么理解呢?当对方 close 一个 Socket 后发送 FIN报文给自己,你系统毫无疑问地会回应一个 ACK 报文给对方,此时则进入到 CLOSE_WAIT 状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close 这个 Socket ,发送 FIN 报文给对方,也即关闭连接。所以你在 CLOSE_WAIT 状态下,需要完成的事情是等待你去关闭连接。

  • (被动方)LAST_ACK :这个状态还是比较容易好理解的,它是被动关闭一方在发送 FIN 报文后,最后等待对方的 ACK报文。当收到 ACK报文后,也即可以进入到 CLOSED 可用状态了。

  • (主动方)TIME_WAIT :表示收到了对方的 FIN 报文,并发送出了 ACK 报文,就等 2MSL 后即可回到 CLOSED 可用状态了。
    如果 FIN_WAIT_1 状态下,收到了对方同时带 FIN 标志和 ACK 标志的报文时,可以直接进入到 TIME_WAIT 状态,而无须经过 FIN_WAIT_2 状态。

    MSL是“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

    为何一定要等 2MSL ?

    如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存活在网络里的老的 TCP 报文可能与新 TCP 连接报文冲突,造成数据冲突,为避免此种情况,需要耐心等待网络老的 TCP 连接的活跃报文全部死翘翘,2MSL 时间可以满足这个需求(尽管非常保守)!

  • CLOSED :表示连接中断。

TIME_WAIT和CLOSE_WAIT状态区别

TIME_WAIT和CLOSE_WAIT状态区别

TCP 数据如何传输?

建立连接后,两台主机就可以相互传输数据了。如下图所示:
计算机网络笔记_第11张图片

  • 上图给出了主机 A 分 2 次(分 2 个数据包)向主机 B 传递 200 字节的过程。
  • 首先,主机 A 通过 1 个数据包发送 100 个字节的数据,数据包的Seq号设置为 1200 。主机 B 为了确认这一点,向主机 A 发送ACK包,并将ack号设置为 1301 。
    • 为了保证数据准确到达,目标机器在收到数据包(包括 SYN包、FIN 包、普通数据包等)包后必须立即回传 ACK 包,这样发送方才能确认数据传输成功。
    • 此时ack号为 1301 而不是 1201,原因在于ack号的增量为传输的数据字节数。假设每次ack号不加传输的字节数,这样虽然可以确认数据包的传输,但无法明确 100 字节全部正确传递还是丢失了一部分,比如只传递了 80 字节。因此按如下的公式确认ack号:ack号 =seq号 + 传递的字节数 + 1 。
      • 与三次握手协议相同,最后加 1 是为了告诉对方要传递的 seq 号。
TCP 数据传输丢失怎么办?什么是 TCP 重传?

因为各种原因,TCP 数据包可能存在丢失的情况,TCP 会进行数据重传。如下图所示:
计算机网络笔记_第12张图片

  • 上图表示通过 seq 1301 数据包向主机 B 传递 100 字节的数据,但中间发生了错误,主机 B 未收到。经过一段时间后,主机 A 仍未收到对于 seq 1301 的 ACK 确认,因此尝试重传数据。为了完成数据包的重传,TCP 套接字每次发送数据包时都会启动定时器,如果在一定时间内没有收到目标机器传回的 ACK 包,那么定时器超时,数据包会重传。上图演示的是数据包丢失的情况,也会有 ACK 包丢失的情况,一样会重传。

  • 重传超时时间(RTO,Retransmission Time Out)

    这个值太大了会导致不必要的等待,太小会导致不必要的重传,理论上最好是网络 RTT 时间,但又受制于网络距离与瞬态时延变化,所以实际上使用自适应的动态算法(例如 Jacobson 算法和 Karn 算法等)来确定超时时间。

    往返时间(RTT,Round-Trip Time)表示从发送端发送数据开始,到发送端收到来自接收端的 ACK确认包(接收端收到数据后便立即确认),总共经历的时延。

  • 重传次数

    TCP 数据包重传次数,根据系统设置的不同而有所区别。有些系统,一个数据包只会被重传 3 次,如果重传 3 次后还未收到该数据包的 ACK 确认,就不再尝试重传。但有些要求很高的业务系统,会不断地重传丢失的数据包,以尽最大可能保证业务数据的正常交互。

    最后需要说明的是,发送端只有在收到对方的 ACK 确认包后,才会清空输出缓冲区中的数据。

ps:TCP 数据传输的过程,和 MQ Broker 投递消息给 Consumer 是一样的,只有在 Consumer Ack 确认消息已经消费,该消息才不会再被投递给 Consumer 。

TCP滑动窗口

在看 TCP 滑动窗口的概念之前,我们先来看看它出现的背景

将 TCP 与 UDP 这样的简单传输协议区分开来的,是它传输数据的质量。TCP 对于发送数据进行跟踪,这种数据管理需要协议有以下两大关键功能:

  • 可靠性:保证数据确实到达目的地。如果未到达,能够发现并重传。
  • 数据流控:管理数据的发送速率,以使接收设备不致于过载。

要完成这些任务,整个协议操作是围绕滑动窗口 + 确认机制来进行的。因此,理解了滑动窗口,也就是理解了 TCP 。

那么,到底什么是 TCP 滑动窗口呢?

滑动窗口协议,是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。

TCP 的滑动窗口解决了端到端的流量控制问题,允许接受方对传输进行限制,直到它拥有足够的缓冲空间来容纳更多的数据。

可能这么描述之后,胖友会有点懵逼,那么建议看下面三篇文章。

  • 《TCP 滑动窗口控制流量的原理》

    比较易懂的一篇文章。

  • 《网络基本功(八):细说 TCP 滑动窗口》

    更为详细的一篇文章。

  • 《TCP 协议的滑动窗口具体是怎样控制流量的?》

    知乎上的讨论,重点看「wuxinliulei」和「安静的木小昊」的回答。特别是后者的,回答很生动形象。

TCP 协议如何来保证传输的可靠性?

TCP 提供一种面向连接的、可靠的字节流服务。其中,面向连接意味着两个使用 TCP 的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个 TCP 连接。

  • 在一个 TCP 连接中,仅有两方进行彼此通信。
  • 而字节流服务意味着两个应用程序通过 TCP 链接交换 8bit 字节构成的字节流,TCP 不在字节流中插入记录标识符。

对于可靠性,TCP 通过以下方式进行保证:

  • 数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时 TCP 发送数据端超时后会重发数据。
  • 对失序数据包重排序:既然 TCP 报文段作为 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此 TC P报文段的到达也可能会失序。TCP 将对失序数据进行重新排序,然后才交给应用层。
  • 丢弃重复数据:对于重复数据,能够丢弃重复数据。
  • 应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。
  • 超时重发:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
  • 流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP 使用的流量控制协议是可变大小的滑动窗口协议

TCP 拥堵

计算机网络中的带宽、交换结点中的缓存及处理机等都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏,这种情况就叫做拥塞

怎么解决 TCP 拥堵?

通过拥塞控制来解决。拥堵控制,就是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。注意,拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。

拥塞控制的方法主要有以下四种:

  1. 慢开始
  2. 拥塞避免
  3. 快重传
  4. 快恢复

1)慢开始

不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。

2)拥塞避免

拥塞避免算法,让拥塞窗口缓慢增长,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1 ,而不是加倍,这样拥塞窗口按线性规律缓慢增长。
计算机网络笔记_第13张图片

3)快重传

快重传,要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方),而不要等到自己发送数据时捎带确认。

快重传算法规定,发送方只要一连收到三个重复确认,就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
计算机网络笔记_第14张图片

4)快恢复

快重传配合使用的还有快恢复算法,当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把 ssthresh 门限减半。

  • 但是接下去并不执行慢开始算法:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。
  • 所以此时不执行慢开始算法,而是将 cwnd 设置为 ssthresh 的大小,然后执行拥塞避免算法。
    计算机网络笔记_第15张图片

UDP

UDP是什么

UDP(User Data Protocol,用户数据报协议),是与 TCP 相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。

主要特点如下:

  • UDP 是无连接的。

  • UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态(这里面有许多参数)。

  • UDP 是面向报文的。

  • UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低。

    对实时应用很有用,如 直播,实时视频会议等

  • UDP 支持一对一、一对多、多对一和多对多的交互通信。

  • UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。

UDP 对应的应用层协议?

  • DNS :用于域名解析服务,将域名地址转换为 IP 地址。DNS 用的是 53 号端口。
  • SNMP :简单网络管理协议,使用 161 号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。
  • TFTP(Trivial File Transfer Protocol):简单文件传输协议,该协议在熟知端口 69 上使用 UDP 服务。

TCP 与 UDP 的区别

TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol) 协议属于传输层协议,它们之间的区别包括:
计算机网络笔记_第16张图片

  • TCP 是面向连接的;UDP 是无连接的。
  • TCP 是可靠的;UDP 是不可靠的。
  • TCP 只支持点对点通信;UDP 支持一对一、一对多、多对一、多对多的通信模式。
  • TCP 是面向字节流的;UDP 是面向报文的。
  • TCP 有拥塞控制机制;UDP 没有拥塞控制,适合媒体通信。
  • TCP 首部开销(20 个字节),比 UDP 的首部开销(8 个字节)要大。
为什么 TCP 叫数据流模式? UDP 叫数据报模式?

所谓的“流模式”,是指TCP 发送端发送几次数据和接收端接收几次数据是没有必然联系的

  • 比如你通过 TCP 连接给另一端发送数据,你只调用了一次 write ,发送了 100 个字节,但是对方可以分 10 次收完,每次 10 个字节;你也可以调用 10 次 write ,每次 10 个字节,但是对方可以一次就收完。
  • 原因:这是因为 TCP 是面向连接的,一个 Socket 中收到的数据都是由同一台主机发出,且有序地到达,所以每次读取多少数据都可以。

所谓的“数据报模式”,是指 UDP 发送端调用了几次 write ,接收端必须用相同次数的 read 读完

  • UDP 是基于报文的,在接收的时候,每次最多只能读取一个报文,报文和报文是不会合并的,如果缓冲区小于报文长度,则多出的部分会被丢弃。
  • 原因:这是因为 UDP 是无连接的,只要知道接收端的 IP 和端口,任何主机都可以向接收端发送数据。这时候,如果一次能读取超过一个报文的数据,则会乱套。

UDP 报文的格式

计算机网络笔记_第17张图片

16 位 * 4 = 64 位 = 8 字节。

UDP 报文中每个字段的含义如下:

源端口:这个字段占据 UDP 报文头的前 16 位,通常包含发送数据报的应用程序所使用的 UDP 端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选的,所以发送端的应用程序不一定会把自己的端口号写入该字段中。如果不写入端口号,则把这个字段设置为 0。这样,接收端的应用程序就不能发送响应了。

目的端口:接收端计算机上 UDP 软件使用的端口,占据 16 位。

长度:该字段占据 16 位,表示 UDP 数据报长度,包含 UDP 报文头和 UDP 数据长度。因为 UDP 报文头长度是 8 个字节,所以这个值最小为 8。

校验值:该字段占据 16 位,可以检验数据在传输过程中是否被损坏。

DNS

DNS 是什么?

DNS协议的作用是将域名解析为IP。能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。

DNS 协议运行在 UDP 协议之上,使用端口号 53 。

​ 世界各地有很多DNS服务器,ISP会给我们提供默认的DNS服务器,也有一些大型公用的DNS服务器可以使用,比如Google的8.8.8.8和国内的114.114.114.114。
​ 我们直接访问的DNS服务器叫本地DSN服务器,它本身也没有域名和IP的对应关系,在我们发出请求的时候它会从主DNS服务器获取然后保存到缓存中,下次再有相同的域名请求时直接从缓存中获取就可以了。

主机解析域名的顺序?

  1. 浏览器缓存

  2. 找本机的 hosts 文件

  3. 路由缓存

  4. 找 DNS 服务器(本地域名、顶级域名、根域名)

    • 迭代查询

      DNS 服务器的一种查询方式为迭代查询,DNS 服务器会向客户机提供其他能够解析查询请求的DNS 服务器地址,当客户机发送查询请求时,DNS 服务器并不直接回复查询结果,而是告诉客户机另一台DNS 服务器地址,客户机再向这台DNS 服务器提交请求,依次循环直到返回查询的结果

    • 递归查询

      递归查询是一种DNS 服务器的查询模式,在该模式下DNS 服务器接收到客户机请求,必须使用一个准确的查询结果回复客户机。如果DNS 服务器本地没有存储查询DNS 信息,那么该服务器会询问其他服务器,并将返回的查询结果提交给客户机。
      计算机网络笔记_第18张图片

DNS 使用什么协议?

参见 《DNS使用的是 TCP 协议还是 UDP 协议》 文章。

既使用 TCP 又使用 UDP 。

  • 区域传送时使用 TCP 协议。

    • 辅域名服务器会定时(一般时 3 小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用 TCP 而不是 UDP ,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。
    • TCP 是一种可靠的连接,保证了数据的准确性。
  • 域名解析时使用 UDP 协议。

    • 客户端向 DNS 服务器查询域名,一般返回的内容都不超过 512 字节,用 UDP 传输即可。

      UDP 报文的最大长度为 512 字节。

    • 不用经过 TCP 三次握手,这样 DNS 服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向 DNS 服务器查询的时候使用 TCP ,但事实上,很多 DNS 服务器进行配置的时候,仅支持 UDP 查询包。

HTTP

HTTP 协议,是 Hyper Text Transfer Protocol(超文本传输协议)的缩写。HTTP协议是建立在客户端和服务器之间的一个应用层协议,在客户端和服务器之间需要数据的传输,而传输数据的时候,我们要遵按照指定的规则或者叫协议去传输数据。

  • HTTP是建立在TCP/IP协议基础之上的一个网络协议。
  • HTTP协议属于网络七层结构中最上层(应用层)的协议。
  • HTTP协议是一个无状态协议(不会记录每次访问时的信息)
  • HTTP是一个客户端和服务器端请求和应答的标准(TCP )。客户端是终端用户,服务器端是网站。

HTTP的作用

为了约束客户端和服务端直接传输web资源时的格式。

HTTP协议组成

HTTP协议由两部分组成:请求协议信息响应协议信息

请求协议信息

HTTP请求协议:
计算机网络笔记_第19张图片

由三部分组成。

  • 请求行:用来说明请求类型,要访问的资源以及所使用的 HTTP 版本。(请求方法 URI 协议/版本 回车换行)

    ​ GET /user.html HTTP/1.1

    ​ 请求方法:GET、POST、HEAD、PUT、DELETE、TRACE、OPTIONS、CONNECT

  • 请求头部: 请求头的信息是以[key : value]形式展现的。

    ​ 用来说明服务器要使用的附加信息从第二行起为请求头部。

    • Content-Type:表示请求正文中的文档属于什么MIME类型。Content-Type:[type]/[subtype];parameter。例如:text/html。
    • HOST:指定请求资源的Internet主机和端口号。
    • Cookie:最重要的请求头信息之一。
    • User-Agent :浏览器类型(客户端类型),如果Servlet返回的内容与浏览器类型有关则该值非常有用。服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础。该信息由你的浏览器来定义,并且在每个请求中自动发送等等。
  • 空行:请求头部后面的空行是必须的。

  • 请求数据、请求体:可以添加任意的其他数据。

    GET请求的请求体是空的,请求参数都是通过请求行传给服务器端。

    POST请求的请求体可以承载数据,请求头和请求体之间有一个空行作为分割线。

    application/x-www-form-urlencoded :会对中文进行URL编码 ,并且多个参数以&连接 , 上传文件只能上传文件名称。
    text/plain :纯文本方式,不会对中文进行URL编码,不会使用&连接多个key-value参数,上传文件只能上传文件名称。
    multipart/form-data :多部件表现形式,这种方式主要可以完成文件上传,可以将上传的文件名称和文件内容都传递给服务器端。

HTTP 协议包括哪些请求?
  • GET: 对服务器资源的简单请求。
  • POST: 用于发送包含用户提交数据的请求。
  • HEAD:类似于 GET 请求,不过返回的响应中没有具体内容,用于获取报头。
  • PUT:传说中请求文档的一个版本。
  • DELETE:发出一个删除指定文档的请求。
  • TRACE:发送一个请求副本,以跟踪其处理进程。
  • OPTIONS:返回所有可用的方法,检查服务器支持哪些方法。
  • CONNECT:用于 SSL 隧道的基于代理的请求。
GET 和 POST 的区别
请求方式 数据位置 明文密文 数据安全 长度限制 应用场景
GET HTTP 请求的 path 中 明文 不安全 长度较小,一般 2k 查询数据
POST HTTP 请求 body 中 可明可密 安全 支持较大数据传输 修改数据
  • 提交数据的方式不同:GET是通过请求行提交请求参数的;POST是通过请求体提交请求参数的。

  • 使用场景不同: GET请求的目的是获取数据,客户端向服务器端要东西。

    ​ POST请求的目的是给服务器提交数据,就是客户端向服务器端给东西。

  • 传递参数的大小不同:

    • GET请求是通过请求行中的请求URL传递给客户端的。HTTP协议对请求URL的长度没有限制,但是不同的浏览器对请求URL长度是有限制的。

    • POST请求是通过请求体传递请求参数的。 POST传递的请求参数大小比GET方式要大,要多。

  • GET 请求可被缓存;POST 请求不会被缓存。

  • GET 请求可被收藏为书签;POST 不能被收藏为书签。

对于 GET 方式的请求,浏览器会把 HTTP header 和 data 一并发送出去,服务器响应 200(返回数据)。

而对于 POST,浏览器先发送 header ,服务器响应 100 continue ,浏览器再发送 data ,服务器响应 200 ok(返回数据)。

也就是说,GET 只需要汽车跑一趟就把货送到了,而 POS T得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

响应协议信息

HTTP响应协议
计算机网络笔记_第20张图片

由三部分组成。状态行、响应头、响应体(响应正文)

  • 状态行:由 协议/版本号、状态码、状态消息三部分组成。

    HTTP/1.1 200 OK

  • 响应头:响应头中的信息以[key, value]方式展现的。 用来说明客户端要使用的一些附加信息。

    • Content-Type:表示请求正文中的文档属于什么MIME类型。Content-Type:[type]/[subtype];parameter。例如:text/html。
    • Content-Length:表示响应消息正文的长度。
    • Allow:服务器支持哪些请求方法(如GET、POST等)。
    • ...
  • 空行:消息报头后面的空行是必须的。

  • 响应体:响应正文,里面包含服务器发给客户端的web资源信息。服务器返回给客户端的文本信息。

    ​ 响应正文信息返回到浏览器时,浏览器需要根据响应头中Content-type设置的MIME类型来打开响应正文信息。

URI 和 URL的区别

URI: uniform Resource Identifier,统一资源标识符。它相当于一个网络资源的名称,只是名称的表现形式是/开头的路径形式。
URL: Uniform Resource Location,统一资源定位符
URL 和 URI 的区别:URL是URI的子集。

HTTP 有哪些状态码?
  • 1×× : 请求处理中,请求已被接受,正在处理
  • 2×× : 请求成功,请求被成功处理
    • 200 OK // 客户端请求成功
  • 3×× : 重定向,要完成请求必须进行进一步处理
    • 301 Moved Permanently // 永久重定向,使用域名跳转
    • 302 Found // 临时重定向,未登陆的用户访问用户中心重定向到登录页面
  • 4×× : 客户端错误,请求不合法
    • 400 Bad Request // 客户端请求有语法错误,不能被服务器所理解
    • 401 Unauthorized // 请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
    • 403 Forbidden // 服务器收到请求,但是拒绝提供服务
    • 404 Not Found // 请求资源不存在,eg:输入了错误的 URL
  • 5×× : 服务器端错误,服务器不能处理合法请求
    • 500 Internal Server Error // 服务器发生不可预期的错误
    • 503 Server Unavailable // 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

HTTP协议版本

现在有哪些版本:

​ HTTP1.1(推荐)、HTTP1.0

HTTP1.1和HTTP1.0的区别:

最大的区别:可以连接传输多个web资源。

  • 1、可扩展性

  • 2、缓存

  • 3、带宽优化

    带来了分块传输 。可能的话,面试也会问。

  • 4、长连接

    HTTP1.1 支持 长连接请求的流水线

    • 长连接(PersistentConnection):处理在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟

      在 HTTP1.1中 默认开启Connection:keep-alive ,一定程度上弥补了 HTTP1.0 每次请求都要创建连接的缺点。

    • 请求的流水线(Pipelining):HTTP1.1 还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。

  • 5、消息传递

  • 6、Host 头域

  • 7、错误提示

  • 8、内容协商

一次完整的 HTTP 请求所经历的步骤

  1. DNS 解析(通过访问的域名找出其 IP 地址,递归搜索)。

  2. HTTP 请求,当输入一个请求时,建立一个 Socket 连接发起 TCP的 3 次握手。

    如果是 HTTPS 请求,会略微有不同。等到 HTTPS 小节,我们在来讲。

  3. (1) 客户端向服务器发送请求命令(一般是 GET 或 POST 请求)。

    这个是补充内容,面试一般不用回答。

    客户端的网络层不用关心应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,我不作过多的描述,无非就是通过查找路由表决定通过那个路径到达服务器。

    客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定 IP 地址的 MAC 地址,然后发送 ARP 请求查找目的地址,如果得到回应后就可以使用 ARP 的请求应答交换的 IP 数据包现在就可以传输了,然后发送 IP 数据包到达服务器的地址。

    (2) 客户端发送请求头信息和数据。

  4. (1) 服务器发送应答头信息。

    (2) 服务器向客户端发送数据。

  5. 服务器关闭 TCP 连接(4次挥手)。

    这里是否关闭 TCP 连接,也根据 HTTP Keep-Alive 机制有关。

    同时,客户端也可以主动发起关闭 TCP 连接。

  6. 客户端根据返回的 HTML、CSS、JS 进行渲染。
    计算机网络笔记_第21张图片

HTTPS(todo)

什么是 HTTPS

HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这些内容加密,确保信息传输安全。最后一个字母 S 指的是 SSL/TLS 协议,它位于 HTTP 协议与 TCP/IP 协议中间。主要用到对称加密、非对称加密、证书等技术进行客户端与服务器的数据加密传输,最终达到保证整个通信的安全性。

HTTP + 加密 + 认证 + 完整性保护 = HTTPS
计算机网络笔记_第22张图片

HTTP 和 HTTPS 的区别

  • 端口不同:HTTP 与 HTTPS 使用不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

    实际 HTTPS 也是可以使用 80 端口,但是考虑继续保持 HTTP 的兼容,只好退而求其次,使用 443 端口。

  • 资源消耗:和 HTTP 通信相比,HTTPS 通信会由于加解密处理消耗更多的 CPU 和内存资源。

  • 开销:HTTPS 通信需要证书,而证书一般需要向认证机构申请免费或者付费购买。

    HTTPS 可以有效的防止运营商劫持,解决了防劫持的一个大问题。

什么是 SSL/ TLS

其中,SSL 是安全套接层(secure sockets layer);TLS 是 SSL 的继任者,叫传输层安全(transport layer security)。

它们存在的唯一目的就是保证上层通讯安全的一套机制

它的发展依次经历了下面几个时期,像手机软件升级一样,每次更新都添加或去除功能,比如引进新的加密算法,修改握手方式等。

  • SSL1.0: 已废除
  • SSL2.0: RFC6176 ,已废除
  • SSL3.0: RFC6101 ,基本废除
  • TLS1.0: RFC2246 ,目前大都采用此种方式
  • TLS1.1: RFC4346
  • TLS1.2: RFC5246 ,没有广泛使用
  • TLS1.3: IETF 正在酝酿中

SSL/TLS 协议作用

  1. 认证用户和服务器,确保数据发送到正确的客户机和服务器。

    客户端必须避免中间人攻击,即除了真正的服务器,任何第三方都无法冒充服务器。

  2. 加密数据以防止数据中途被窃取。

  3. 维护数据的完整性,确保数据在传输过程中不被改变。

SSL 加密方式

对称密钥加密,是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方。

非对称加密,指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。

  • 在建立传输链路时,SSL 首先对对称加密的密钥使用公钥进行非对称加密。

    这里 Server 返回给 Client 的不是公钥( server.pub ),而是 server.crt 。Client 需要使用 ca.keyserver.crt 中解密出公钥( server.pub ) 。

  • 链路建立好之后,SSL 对传输内容使用公钥( server.pub )对称加密。

为什么公钥传输的步骤这么复杂呢?

答案请看 《九个问题从入门到熟悉 HTTPS》 文章的如下问题:

  • Q5: 那公钥怎么传输
  • Q6: 你在逗我么。。。。
  • Q7: 怎么知道证书有没有被篡改?
  • Q8: 这样可以防止第三方冒充服务器么

也就是说,通过 CA 来保证。至于 server.crt 证书是怎么申请的呢?请看 《SSL/TLS 双向认证(一) – SSL/TLS工作原理》 文章的 CA 的证书 ca.crt 和 SSL Server 的证书 server.crt 是什么关系呢? 问题的解答。

什么是单向认证、双向认证?

  • 单向认证,指的是只有一个对象校验对端的证书合法性。

    通常都是 Client 来校验服务器的合法性。那么 Client 需要一个ca.crt ,服务器需要 server.crtserver.key

  • 双向认证,指的是相互校验,Server 需要校验每个 Client ,Client 也需要校验服务器。

    • Server 需要 server.keyserver.crtca.crt
    • Client 需要 client.keyclient.crtca.crt
单向认证的过程
计算机网络笔记_第23张图片
  1. 客户端向服务端发送 SSL 协议版本号、加密算法种类、随机数等信息。

  2. 服务端给客户端返回 SSL 协议版本号、加密算法种类、随机数等信息,同时也返回服务器端的证书,即公钥证书。

  3. 客户端使用服务端返回的信息验证服务器的合法性,包括:

  • 证书是否过期。

  • 发型服务器证书的 CA 是否可靠。

  • 返回的公钥是否能正确解开返回证书中的数字签名。

  • 服务器证书上的域名是否和服务器的实际域名相匹配

    验证通过后,将继续进行通信;否则,终止通信。

  1. 客户端向服务端发送自己所能支持的对称加密方案,供服务器端进行选择。
  2. 服务器端在客户端提供的加密方案中选择加密程度最高的加密方式。
  3. 服务器将选择好的加密方案通过明文方式返回给客户端。
  4. 客户端接收到服务端返回的加密方式后,使用该加密方式生成产生随机码,用作通信过程中对称加密的密钥,使用服务端返回的公钥进行加密,将加密后的随机码发送至服务器。
  5. 服务器收到客户端返回的加密信息后,使用自己的私钥进行解密,获取对称加密密钥。

在接下来的会话中,服务器和客户端将会使用该密码进行对称加密,保证通信过程中信息的安全

双向认证的过程

双向认证和单向认证原理基本差不多,只是除了客户端需要认证服务端以外,增加了服务端对客户端的认证,具体过程如下:
计算机网络笔记_第24张图片

  1. 客户端向服务端发送 SSL 协议版本号、加密算法种类、随机数等信息。
  2. 服务端给客户端返回 SSL 协议版本号、加密算法种类、随机数等信息,同时也返回服务器端的证书,即公钥证书。
  3. 客户端使用服务端返回的信息验证服务器的合法性,包括:
  • 证书是否过期。

  • 发型服务器证书的 CA 是否可靠。

  • 返回的公钥是否能正确解开返回证书中的数字签名。

  • 服务器证书上的域名是否和服务器的实际域名相匹配

    验证通过后,将继续进行通信;否则,终止通信。

  1. 服务端要求客户端发送客户端的证书,客户端会将自己的证书发送至服务端。

  2. 验证客户端的证书,通过验证后,会获得客户端的公钥。

  3. 客户端向服务端发送自己所能支持的对称加密方案,供服务器端进行选择。

  4. 服务器端在客户端提供的加密方案中选择加密程度最高的加密方式。

  5. 服务器将选择好的加密方案通过明文方式返回给客户端。

  6. 客户端接收到服务端返回的加密方式后,使用该加密方式生成产生随机码,用作通信过程中对称加密的密钥,使用服务端返回的公钥进行加密,将加密后的随机码发送至服务器。

  7. 服务器收到客户端返回的加密信息后,使用自己的私钥进行解密,获取对称加密密钥。

    在接下来的会话中,服务器和客户端将会使用该密码进行对称加密,保证通信过程中信息的安全

如何选择单向认证还是双向认证

一般一个站点很多用户访问就用单向认证。

企业接口对接就用双向认证。

如果想要提高 APP 的安全级别,也可以考虑双向认证。因为,APP 天然方便放入客户端证书,从而提高安全级别。

为什么抓包工具还能抓到 HTTPS 数据包并解密成功呢

不是说HTTPS在网络中传输的是密文吗?这个问题就是中间者攻击(man in zhe middle)。
计算机网络笔记_第25张图片

  • 解决办法,就是 HTTPS 单向验证。在客户端中内置服务器公钥,在第三步服务器返回的公钥,除了验证公钥的有效性之外,再比对公钥是不是和内置的公钥一样,不一样说明被中间者攻击了,就断开链接不在请求了。
  • 这个原理的前提是服务器的私钥没有泄露,客户端的代码不会被破解,道高一尺魔高一丈。信息安全就是在合理的范围内,选择比较合适的加密方法,没有绝对论,只有相对论。在某个范围内比较安全。

HTTPS 握手会影响性能么?

TCP 有三次握手,再加上 HTTPS 的四次握手,影响肯定有,但是可以接受。

  • 首先,HTTPS 肯定会更慢一点,时间主要花费在两组 SSL 之间的耗时和证书的读取验证上,对称算法的加解密时间几乎可以忽略不计。
  • 而且如果不是首次握手,后续的请求并不需要完整的握手过程。客户端可以把上次的加密情况直接发送给服务器从而快速恢复,具体细节可以参考 《图解 SSL/TLS 协议》 。
  • 除此以外,SSL 握手的时间并不是只能用来传递加密信息,还可以承担起客户端和服务器沟通 HTTP2 兼容情况的任务。因此从 HTTPS 切换到 HTTP2.0 不会有任何性能上的开销,反倒是得益于 HTTP2.0 的多路复用等技术,后续可以节约大量时间。
  • 如果把 HTTPS2.0 当做目标,那么 HTTPS 的性能损耗就更小了,远远比不上它带来的安全性提升。

HTTP 2.0

HTTP 2.0是什么?

HTTP2.0 ,可以说是SPDY的升级版(其实原本也是基于SPDY设计的),但是,HTTP2.0 跟 SPDY 仍有不同的地方,如下:

  • HTTP2.0 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS 。
  • HTTP2.0 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DEFLATE 。
SPDY是什么?

2012 年,Google 如一声惊雷提出了 SPDY 的方案,优化了 HTTP1.X 的请求延迟,解决了 HTTP1.X 的安全性,具体如下:

  • 1、降低延迟

    针对 HTTP 高延迟的问题,SPDY 优雅的采取了多路复用(multiplexing)。多路复用通过多个请求 Stream 共享一个 Tcp连 接的方式,解决了 HOL blocking 的问题,降低了延迟同时提高了带宽的利用率。

  • 2、请求优先级(request prioritization)

    多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY 允许给每个 request 设置优先级,这样重要的请求就会优先得到响应。

    比如浏览器加载首页,首页的 html 内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。

  • 3、header 压缩

    前面提到 HTTP1.x 的 header 很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。

  • 4、基于 HTTPS 的加密协议传输

    大大提高了传输数据的安全性。

  • 5、服务端推送(server push)

    采用了 SPDY 的网页,例如我的网页有一个 sytle.css 的请求,在客户端收到 sytle.css 数据的同时,服务端会将 sytle.js 的文件推送给客户端。当客户端再次尝试获取 sytle.js 时就可以直接从缓存中获取到,不用再发请求了。

    和我们理解的服务端推送,有点(非常)不一样哈。

SPDY 构成图:

SPDY 位于 HTTP 之下,TCP 和 SSL 之上,这样可以轻松兼容老版本的 HTTP 协议(将 HTTP1.x 的内容封装成一种新的 frame 格式),同时可以使用已有的 SSL 功能。
计算机网络笔记_第26张图片

HTTP2.0 和 HTTP1.X 相比的新特性

计算机网络笔记_第27张图片

  • 1、新的二进制格式(Binary Format)

    HTTP1.x 的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认 0 和 1 的组合。基于这种考虑 HTTP2.0 的协议解析决定采用二进制格式,实现方便且健壮。

  • 同 SPDY 对 HTTP1.1 的改进。

    • 2、降低延迟
    • 3、多路复用(MultiPlexing) 见下文
    • 4、header 压缩 见下文
    • 5、服务端推送(server push) 见下文

HTTP2.0 的多路复用和 HTTP1.X 中的长连接复用的区别

  • HTTP/1.0:一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接。
  • HTTP/1.1:Pipeling 解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会。一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞。
  • HTTP/2:多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行。
    计算机网络笔记_第28张图片
HTTP2.0 多路复用有多好?

HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。

HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。

为什么需要头部(header)压缩?

假定一个页面有 100 个资源需要加载(这个数量对于今天的 Web 而言还是挺保守的),而每一次请求都有 1kb 的消息头(这同样也并不少见,因为 Cookie 和引用等东西的存在),则至少需要多消耗 100kb 来获取这些消息头。HTTP2.0 可以维护一个字典,差量更新 HTTP 头部,大大降低因头部传输产生的流量。

具体参考:《HTTP/2 头部压缩技术介绍》 文章。

  • 维护一份相同的静态字典(Static Table),包含常见的头部名称,以及特别常见的头部名称与值的组合。
  • 维护一份相同的动态字典(Dynamic Table),可以动态地添加内容。
  • 支持基于静态哈夫曼码表的哈夫曼编码(Huffman Coding)。

服务器推送是什么?

服务端推送能把客户端所需要的资源伴随着 index.html 一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。具体如下:

普通的客户端请求过程
计算机网络笔记_第29张图片

服务端推送的过程
计算机网络笔记_第30张图片

HTTP、TCP、Socket 的关系是什么?

  • TCP/IP 代表传输控制协议/网际协议,指的是一系列协议族。
  • HTTP 本身就是一个协议,是从 Web 服务器传输超文本到本地浏览器的传送协议。
  • Socket 是 TCP/IP 网络的 API ,其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Socket 接口后面。对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议。

综上所述:

  • 需要 IP 协议来连接网络
  • TCP 是一种允许我们安全传输数据的机制,使用 TCP 协议来传输数据的 HTTP 是 Web 服务器和客户端使用的特殊协议。
  • HTTP 基于 TCP 协议,所以可以使用 Socket 去建立一个 TCP 连接。

你可能感兴趣的:(计算机网络笔记)