TCP/IP详解

一、网络基础

这里进行介绍在后面将要详细讨论的许多术语和协议,T C P / I P协议族分为四层:链路层、网络层、运输层和应用层,每一层各有不同的责任。在T C P / I P中,网络层和运输层之间的区别是最为关键的:网络层( I P)提供点到点的服务,而运输层(T C P和U D P)提供端到端的服务。

一个互联网是网络的网络。构造互联网的共同基石是路由器,它们在 I P层把网络连在一起。第一个字母大写的I n t e r n e t是指分布在世界各地的大型互联网,其中包括 1万多个网络和超过1 0 0万台主机。

在一个互联网上,每个接口都用 I P地址来标识,尽管用户习惯使用主机名而不是 I P地址。域名系统为主机名和 I P地址之间提供动态的映射。端口号用来标识互相通信的应用程序。服务器使用知名端口号,而客户使用临时设定的端口号。

1.TCP/IP网络分层

TCP / IP,是一组不同层次上的多个协议的组合,T C P和I P只是其中的两种协议而已,因为历史比较久所以使用TCP/IP进行命名这个协议簇,不过也可以看出这两个协议的重要性。 TCP / IP通常被认为是一个四层协议系统(也有说五层的,官方说法是四层一般不考虑物理层)。如下图:
在这里插入图片描述
他们每一层负责不同的功能:

  • 链路层:
    有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。
  • 网络层:
    有时也称作互联网层,处理分组在网络中的活动,例如分组的选路。在TCP / IP协议族中,网络层协议包括 I P协议(网际协议),I C M P协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。
  • 运输层:
    运输层主要为两台主机上的应用程序提供端到端的通信。在 T C P / I P协议族中,有两个互不相同的传输协议:T C P(传输控制协议)和U D P(用户数据报协议)。T C P为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节(所以网络层即使保证不了通讯的可靠性,TCP依然是可靠的)。而另一方面,U D P则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。任何必需的可靠性必须由应用层来提供。IP不可靠但是TCP针对IP的不可靠提供了很多机制来使得端到端的通讯变得可靠,所以基于TCP的应用他的通讯是可靠的。而UDP是不可靠的,UDP的设计初衷就是为了快而不是可靠,所以一些对速率要求比较高的传输会使用UDP,比如媒体流传输和DNS等都是使用UDP协议的。那DNS这种又是如何依靠不可靠的UDP提供相对可靠的服务呢?以DNS举例来说,虽然在传输层的UDP没做可靠性保证,但是我们可以在应用层进行可靠性保证,这和网络层的IP不可靠,传输层的TCP可靠一个道理,只是把可靠保证前移到了应用层,DNS就是这样,他提供了失败重试机制,多次失败后就会将底层通讯变为TCP从而提供了可靠性保证。
  • 应用层:
    应用层负责处理特定的应用程序细节,比如常见的HTTP、FTP、Telnet、SMTP等都属于应用层协议。

总结来说我们常见的是应用层的通讯,下三层(运输层、网络层、链路层)都是在操作系统内核中的,对于我们来说不可见。当我们在应用层发了一个HTTP请求以后,HTTP请求会被系统内核进行解析先是通过运输层的转化再到网络层再到链路层然后再到另外一台服务器的链路层然后网上进行通讯。发送信息基本如下图红色箭头指向:
在这里插入图片描述
信息回传的话则正好相反。
上面已经介绍了TCP/IP的分层理念,那这些分层里都有哪些典型的协议呢,如下图:
在这里插入图片描述
这里可能需要再说下的是ICMP和IGMP,ARP和RARP了(其他的之前已经简单介绍了,后面都会详细说明)。I C M P是I P协议的附属协议。I P层用它来与其他主机或路由器交换错误报文和其他重要信息,尽管I C M P主要被I P使用,但应用程序也有可能访问它。我
们将分析两个流行的诊断工具,P i n g和Tr a c e r o u t e,它们都使用了I C M P。I G M P是I n t e r n e t组管理协议。它用来把一个 U D P数据报多播到多个主机。至于A R P(地址解析协议)和R A R P(逆地址解析协议)则是非常重要的协议了,它用来解析IP对应的MAC地址。通过域名通讯时需要用DNS解析IP,但是只知道IP服务器之间是无法通讯的必须借助ARP将IP解析为MAC地址才可以实现通讯。

2.IP地址和端口号

  • IP
    互联网上的每个接口必须有一个唯一的 I n t e r n e t地址(也称作 I P地址)。I P地址长32 bit,也就是4个字节,通常使用4个10进制数字来进行表示。每个十进制数字最大为255.IP通常由网络号+主机号进行构成。网络号用于确定当前IP所属的网络,主机号则是为了确定当前网络下的具体IP,同一个网络内IP不可重复。而根据网络号和主机号长度不同可以将IP分为五类:
    在这里插入图片描述
    下面是各类IP地址的范围。
    在这里插入图片描述
    可以看到我们常用的IP大多分布在A类和B类上,因为A类和B类的IP所在的网络可以支持更多的IP地址(网络号越长,主机号越短,容纳的主机自然就越少了),那要如何判断两个IP是否是同一个网段或者说在不在同一个子网内呢?
    先看下各个分类的IP对应的子网掩码:
A类IP地址的第一字节的值为1-127,地址范围为1.0.0.0 - 127.255.255.255,默认子网掩码为255.0.0.0。它适合大型网络。
B类IP地址的第一字节的值为128-191,地址范围为128.0.0.0 - 191.255.255.255,默认子网掩码为255.255.0.0。用于中等规模的网络。
C类IP地址的第一字节的值为192-223,地址范围为192.0.0.0 - 223.255.255.255,默认子网掩码为255.255.255.0。适合小型网络。
D类IP地址的第一字节的值为224-239,是用于多播的IP地址范围。
E类IP地址的第一字节的值为240-255,是一部分专用和保留的IP地址范围

判断两个IP是不是在同一个网段内,可以使用IP与子网掩码的“与”结果进行比较,如果相同则基本表示是在同一个网段内。例如存在两个ip和对应的子网掩码为:

192.168.0.1: 255.255.255.0
192.168.0.2: 255.255.255.0

通过与预算可以得出两个结果都是192.168.0.0,基本可以得出两个IP在同一个网段。需要补充说明的是:
内网IP以192.168、172.16、10为开头,这都是保留的私有IP地址段。其中10开头是的是A类网址预留的内网ip公网不会用,同理172.16是B类网址预留的,192则是C类网址预留的。

  • 端口号
    TCP和UDP使用16bit的端口号来表示程序,16bit最大是65535.在0-1023之前的端口号位linux系统内部使用,基本都已经确定了是不允许随便乱用的。比如常见的FTP的21端口,SSH的22端口、telnet的23端口等等。而在1024和5000之间的端口号一般是系统预留的临时端口,当在服务器发起一个临时程序时,系统会默认分配一个临时端口号给到应用。大于5000的端口号则是给其他服务器进行预留的端口。平时使用的话一般是可以使用1024到5000之间的端口的。

3.封装与分用

这里大致介绍下网络数据从发送到接收返回的一个过程。

  • 封装
    当应用程序使用TCP(以TCP为例)进行数据传输时,数据被送入协议栈中,然后从运输层卓个通过每一次向下传输直到被当做一串bit流传入到网络,其中每一层接收到信息都会增加一些首部信息(用以标识信息的封装层级和模式)。如下图:
    在这里插入图片描述
    假设应用程序时HTTP服务,那么就会有如下过程:
    ①应用层:数据被封装成HTTP报文,会包含请求的头部信息和报文体等信息
    ②运输层:HTTP信息被再次封装,加入TCP头部,TCP头部比较主要的信息有源端口号和目标端口号
    ③网络层:TCP报文段被封装成IP数据报,加入IP头部,IP头部比较重要的信息有源IP和目标IP
    ④链路层:IP数据报被封装成帧,加入以太网头部,以太网头部主要包含源MAC地址和目标MAC地址

  • 分用
    分用正好是封装的反过程,当目的主机收到一个以太网数据帧时,数据就开始从协议栈中由底向上升,同时去掉各
    层协议加上的报文首部。每层协议盒都要去检查报文首部中的协议标识,以确定接收数据的上层协议。这个过程称作分用。如下图:
    在这里插入图片描述
    其实分用的过程就是封装的反过程:
    ①链路层:解析以太网头部,获取目标MAC找到对应主机,去掉头部,传递给网络层
    ②网络层:解析IP头部,获取到目标IP地址获取网络和主机号,去掉IP头部
    ③传输层:解析TCP头部,获取到目标端口
    ④应用层:将HTTP请求发送到目标端口中
    而数据被处理完再次返回时正好有事一个封装和分用的过程。

4.客户-服务端模型

大部分网络程序都是设计成一端是客户、一端是服务。客户端访问服务端时客户端使用随机的端口和服务端特定的端口进行互联。而服务端又可以分为两种类型:重复型、并发型。

  • 重复型服务端:
    UDP服务大多是重复型服务,不是绝对。
    1. 等待一个客户请求的到来。
    2. 处理客户请求。
    3. 发送响应给发送请求的客户。
    4. 返回第1步。
      重复型服务器主要的问题发生在 2状态。在这个时候,它不能为其他客户机提供服务。
  • 并发型服务端:
    大部分网络应用都是并发型的支持多人在线的同时操作,其实就是并发多线程,大部分TCP服务是并发型服务,不是绝对。
    1. 等待一个客户请求的到来。
    2. 启动一个新的服务器来处理这个客户的请求。在这期间可能生成一个新的进程、任务
      或线程,并依赖底层操作系统的支持。这个步骤如何进行取决于操作系统。生成的新服务器
      对客户的全部请求进行处理。处理结束后,终止这个新服务器。
    3. 返回第1步。

二、链路层

在TCP/IP协议簇中,链路层可以看做最底层的模型,主要有三个目的

  • 1 发送IP数据报接收IP数据报,上面已经说了链路层的以太网协议(假设使用的是以太网协议)他会在通讯时将IP的数据报封装在头部,然后交给链路层,链路层接着会在头部进行封装MAC地址等信息然后发送给目标机器。
  • 2 为ARP模块发送ARP请求和接收ARP的应答,上面也说了ARP协议是用来通过IP寻找MAC地址的,网络通讯最终还是依赖MAC地址进行通讯。
  • 3 为RARP模块发送RARP请求和接收RARP的应答。RARP是逆地址解析协议。

需要注意的是TCP/IP支持多种不同的链路层协议,包括常见的以太网此外还有令牌环网等。

1.以太网IEEE802封装

以太网这个术语一般是指数字设备公司( Digital Equipment Corp.)、英特尔公司( I n t e l C o r p .)和X e r o x公司在1 9 8 2年联合公布的一个标准。它是当今 T C P / I P采用的主要的局域网技术。它采用一种称作 C S M A / C D的媒体接入方法,其意思是带冲突检测的载波侦听多路接入(Carrier Sense, Multiple Access with Collision Detection)。它的速率为10 Mb/s,地址为48 bit。几年后,I E E E(电子电气工程师协会) 8 0 2委员会公布了一个稍有不同的标准集。说IEEE可能大部分人不知道,要是说OSI七层网络协议肯定大家都知道,OSI就是IEEE研究后推出的。它定义链路层的不同封装方式,下图是IEEE定义的802封装方式(上)和以太网的封装方式(下):
在这里插入图片描述
其实可以很直观的看到他们的区别以太网的封装是MAC地址后是类型然后就是数据了而802则略有不同,这里只需要知道有这种封装方式即可,不需要太过深入了解。以太网的最大MTU(最大传输单元)是1500字节。上图中的CRC是校验码(可以理解为MD5,CRC的原理就是在传送时根据指定算法计算出一个值,接收时同样根据该算法计算一个值,然后比对是否与帧中的CRC相同,相同则表示没有数据丢失,否则就表示数据有丢失,CRC还可以知道哪个数据丢失了)。
除了他们还有一种尾部封装(被淘汰了)。

2.环回接口 Loopback Interface

大多数的产品都支持环回接口( Loopback Interface),以允许运行在同一台主机上的客户程序和服务器程序通过 T C P / I P进行通信。A类网络号1 2 7就是为环回接口预留的。根据惯例,大多数系统把I P地址1 2 7 . 0 . 0 . 1分配给这个接口,并命名为 l o c a l h o s t。一个传给环回接口的 I P数据报不能在任何网络上出现。
在这里插入图片描述

    1. 传给环回地址(一般是1 2 7 . 0 . 0 . 1)的任何数据均作为I P输入。
    1. 传给广播地址或多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是因为广播传送和多播传送的定义(第 1 2章)包含主机本身。
    1. 任何传给该主机I P地址的数据均送到环回接口。看上去用传输层和 I P层的方法来处理环回数据似乎效率不高,但它简化了设计,因为环回接口可以被看作是网络层下面的另一个链路层。网络层把一份数据报传送给环回接口,就像传给其他链路层一样,只不过环回接口把它返回到 I P的输入队列中。

3.最大传输单元MTU和路径MTU

正如在图2 - 1看到的那样,以太网和8 0 2 . 3对数据帧的长度都有一个限制,其最大值分别是1500和1492字节。链路层的这个特性称作
MTU,最大传输单元。不同类型的网络大多数都有一个上限。
在这里插入图片描述
如果 I P层有一个数据报要传,而且数据的长度比链路层的 MTU还大,那么 I P层就需要进行分片( f r a g m e n t a t i o n)(这就是IP的数据报的分片),把数据报分成若干片,这样每一片都小于 MTU。
路径MTU:当在同一个网络上的两台主机互相进行通信时,该网络的 M T U是非常重要的。但是如果两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的 M T U。重要的不是两台主机所在网络的 M T U的值,重要的是两台通信主机路径中的最小 MTU。它被称作路径MTU。
两台主机之间的路径 M T U不一定是个常数。它取决于当时所选择的路由。而选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径M T U在两个方向上不一定是一致的。

三、网络层 - IP

I P是TCP / IP协议族中最为核心的协议。所有的 TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输. IP具有不可靠、无连接的特点。

  • 不可靠:
    不可靠的意思是它不能保证 IP数据报能成功地到达目的地。 IP仅提供最好的传输服务。如果发生某种错误时,如某个路由器暂时用完了缓冲区, IP有一个简单的错误处理算法:丢弃该数据报,然后发送 ICMP消息报给信源端。任何要求的可靠性必须由上层来提供(如TCP)。
  • 无连接:
    无连接这个术语的意思是 IP并不维护任何关于后续数据报的状态信息。每个数据报的处理是相互独立的。这也说明, I P数据报可以不按发送顺序接收。如果一信源向相同的信宿发送两个连续的数据报(先是 A,然后是B),每个数据报都是独立地进行路由选择,可能选择不同的路线,因此 B可能在A到达之前先到达。

1.IP首部的关键信息

下图是IP首部的信息图
在这里插入图片描述
4位版本:目前的协议版本号是4,因此I P有时也称作IPv4
4位首部长度:说是现在已经没啥用了。
16位总长度:总长度字段是指整个 I P数据报的长度,以字节为单位。利用首部长度字段和总长度字段,就可以知道 I P数据报中数据内容的起始位置和长度。由于该字段长 1 6比特,所以 I P数据报最长可达 6 5 5 3 5字节。这里就需要说下TCP和UDP了,TCP会对用户数据进行拆分,所以一般IP的限制不会影响到TCP,但是UDP并没有对数据进行处理,所以IP就需要位UDP的协议进行分片处理。
8位生存时间:TTL(t i m e - to - live)生存时间字段设置了数据报可以经过的最多路由器数。它指定了数据报的生存时间。T T L的初始值由源主机设置(通常为 3 2或6 4),一旦经过一个处理它的路由器,它的值就减去 1。当该字段的值为 0时,数据报就被丢弃,并发送 ICM P报文通知源主机。这个特性可以防止IP数据报在网络间无限的传送,如果把TTL设置为64,那么数据传输最多经过64跳,若是64跳后仍没有到达目的地,则会使用ICMP报文通知源主机返回给其错误提示。
首部检验和:首部检验和字段是根据I P首部计算的检验和码。它不对首部后面的数据进行计算。 ICMP、IGMP、UDP和TCP在它们各自的首部中均含有同时覆盖首部和数据检验和码。数据接收方就是通过重新计算首部检验和来判断IP数据是否有丢失的。

2.IP路由选择

IP路由选择是指决定数据包从源主机传输到目标主机所需的路径的过程。在TCP/IP协议中,路由选择是由路由器(或交换机)执行的。路由选择的目标是在网络中找到最佳路径,以最有效地将数据包从源传输到目标。

IP可以从TCP、UDP、ICMP和IGMP接收数据报(即在本地生成的数据报)并进行发送,或者从一个网络接口接收数据报(待转发的数据报)并进行发送。 I P层在内存中有一个路由表。当收到一份数据报并进行发送时,它都要对该表搜索一次。当数据报来自某个网络接口时,I P首先检查目的I P地址是否为本机的I P地址之一或者I P广播地址。如果确实是这样,数据报就被送到由 I P首部协议字段所指定的协议模块进行处理。如果不是则开始对路由表进行搜索然后进行网络传递。那IP是如何来实现通过路由表来找到目标主机的呢?

  • 路由表查找:
    路由器拥有一个路由表,其中包含了关于不同网络地址(或网络地址前缀)的信息。每个路由表项通常包括以下信息:

    • 目标网络地址(或网络地址前缀):这是数据包的目标IP地址的一部分,通常是一个网络地址或网络地址前缀。这个字段用来匹配数据包的目标。

    • 下一跳路由器:这是数据包应该被发送到的下一个路由器的IP地址。这是确定数据包应该经过哪个路由器的关键信息。

    • 出接口:这是路由器的物理或逻辑接口,通过这个接口数据包将被发送到下一跳路由器

    假设有一个路由表如下:
    目标网络地址前缀:192.168.1.0/24,下一跳路由器:RouterA
    目标网络地址前缀:192.168.1.128/25,下一跳路由器:RouterB
    目标网络地址前缀:192.168.2.0/24,下一跳路由器:RouterC
    现在,假设一个数据包的目标IP地址是192.168.1.130。系统需要确定数据包的下一跳路由器。使用最长前缀匹配,系统会比较目标IP地址(192.168.1.130)与路由表中的不同目标网络地址前缀:
    第一项:192.168.1.0/24,前缀长度24位
    第二项:192.168.1.128/25,前缀长度25位
    第三项:192.168.2.0/24,前缀长度24位
    在这个例子中,192.168.1.128/25 的前缀长度(25位)比 192.168.1.0/24(24位)更长,因此它是最长前缀匹配。
    因此,数据包将被发送到下一跳路由器 RouterB,以便继续其路由路径。
    
  • 最佳路径选择:
    路由器会使用不同的路由选择算法来确定最佳路径。这通常涉及到比较目标地址与路由表中的条目,然后选择具有最长匹配前缀(Longest Prefix Match)的路由条目,以确定下一跳路由器。这是常用的路由选择算法,它允许路由器选择最精确的匹配,以确保数据包沿着正确的路径转发。

  • 数据包转发:
    一旦确定了下一跳路由器,路由器将数据包发送到该路由器,然后该路由器继续进行路由选择,直到数据包到达目标网络。

3.子网寻址和子网掩码

  • 子网寻址
    现在所有的主机都要求支持子网编址。不再是把IP地址看成由单纯的一个网络号和一个主机号组成,而是把主机号再分成一个子网号和一个主机号。以更精细地控制网络资源和提高网络管理的灵活性,子网寻址可用于拆分大型网络,以减小广播域、提高网络性能和加强网络安全性。

  • 子网掩码
    子网掩码用来控制多少比特用于子网号及多少比特用于主机号,有了子网掩码我可以清晰的知道两个ip的网络号与子网号是否相同。子网掩码一般也就是用来做这个事情的。
    在这里插入图片描述

    举个例子:
    假设我们的主机地址是 140.252.1.1(一个B类地址),而子网掩码为255.255.255.0(其中8bit为子网号,8 bit为主机号)。
    • 如果目的I P地址是140.252.4.5,那么我们就知道 B类网络号是相同的( 140.252),但是
    子网号是不同的(1和4)。用子网掩码在两个I P地址之间的比较如图3 - 8所示。
    • 如果目的I P地址是140.252.1.22,那么B类网络号还是一样的( 140.252),而且子网号也是一样的(1),但是主机号是不同的。
    • 如果目的I P地址是192.43.235.6(一个C类地址),那么网络号是不同的,因而进一步的比较就不用再进行了。
    

4.ICMP和IGMP

  • ICMP Internet控制报文协议
    ICMP经常被认为是 I P层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被I P层或更高层协议( TCP或UD P)使用。一些 ICMP报文把差错报文返回给用户进程,ICMP是在IP数据报内部进行传输的。
    在这里插入图片描述
    事实上ICMP大部分场景都是用来当IP通讯出现问题时用户通知调用方哪里错了,并且会在ICMP报文内部封装具体的错误码已告诉调用方错误信息。

  • IGMP:Internet组管理协议
    IGMP协议在多播网络中的主要作用是协调多播组的成员关系,以确保只有对特定多播组感兴趣的主机才会接收和处理相关的多播数据。这提高了多播网络的效率,减少了不必要的数据传输,同时也有助于节省网络带宽。
    在这里插入图片描述

    他有如下作用(主要是多播管理):
    加入多播组: 主机可以使用IGMP协议向本地路由器发送加入多播组的请求,以表示它希望接收特定多播组的数据。这有助于路由器知道哪些主机对哪些多播组感兴趣。
    离开多播组: 当主机不再对特定多播组感兴趣时,它可以使用IGMP协议向本地路由器发送离开多播组的请求。这有助于路由器及时停止向不感兴趣的主机发送多播数据。
    路由器处理: 路由器在多播网络中起到关键作用,它负责维护多播组的成员关系信息,并根据这些信息正确地转发多播数据。IGMP使路由器能够了解哪些主机位于哪些多播组中,从而有效地路由多播数据。
    查询和报告: 路由器可以周期性地向本地网络上的主机发送IGMP查询消息,以了解哪些多播组的成员仍然存在。主机会回复这些查询消息,向路由器报告其成员关系。

四、传输层 - TCP

传输层的协议主要是TCP和UDP,这个章节主要讨论的是TCP。

1.TCP的特点

TCP的特点是面向连接的、可靠的字节流服务
在这里插入图片描述

  • 面向连接的:面向连接意味着两个使用 TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个 TCP连接,TCP为应用层提供全双工服务。这意味数据能在两个方向上独立地进行传输,通常所说的TCP的三次握手也就是TCP建立连接的过程,后面将详细讨论TCP的三次握手的过程。

  • 可靠的:TCP的可靠性由TCP提供的几方面的特性共同保证

      1. 数据分段:TCP的数据会自动分段成固定长度,这和UDP不同,UDP需要依赖IP层的分片,而TCP不需要。
      1. 超时重传:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
      1. ACK应答:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒,
      1. 首部检验和:首部检验和保证数据传输过程不丢失,丢失则重传(接收方会重新根据内容计算检验和)。
      1. 支持对接收数据的排序:字节流: 既然TCP报文段作为I P数据报来传输,而 I P数据报的到达可能会失序,因此 TCP报文段的到达也可能会失序。如果必要, TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。
      1. 重复丢弃:可以识别重复推送的数据并进行丢弃。
      1. 流量控制:T C P连接的每一方都有固定大小的缓冲空间。 T C P的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。

    TCP通过以上特点保证了他是一个可靠的传输层协议,这点与UDP在设计上是本质区别的。

  • 字节流服务:两个应用程序通过T C P连接交换8 bit字节构成的字节流。T C P不在字节流中插入记录标识符。我们将这称为字节流服务。

2 TCP首部

在说TCP的三次握手之前必须要了解下TCP的首部和他首部中的标志比特。
下图是TCP首部的解析图:
在这里插入图片描述

  • 16位源端口号:就是TCP客户端的端口号,这个很好理解(216=65536,所以端口号最大是65535) 。

  • 16位目标端口号:就是TCP服务端的端口号。

  • 32位序号:用于对数据进行排序和重新组装。用于建立可靠的数据传输。

  • 32位确认序号:如果ACK标志被设置为1,这个字段包含对已经收到的字节的确认号(服务端返回客户端的序号),用于确认收到的数据。

  • 4位首部长度:用于表示TCP首部的长度,因首部中存在可变长度的数据,需要使用长度进行标识。

  • 6位控制位:用于控制TCP连接的状态和行为,其中包括

      1. URG(紧急)标志位:
        URG标志位被设置为1时,表示数据包中包含紧急数据,需要尽快处理。
        URG标志通常与紧急指针(Urgent Pointer)字段一起使用,该字段指示了数据中的紧急数据的位置。
        通常情况下,URG标志和紧急指针用于高优先级数据,以便尽快传递给应用程序。
      1. ACK标志位(Acknowledgment):
        当ACK标志位被设置为1时,表示数据包中包含了对之前数据包的确认信息。
        当ACK标志位被设置为0时,表示数据包中没有确认信息或者不是用于确认的目的
      1. PSH(推送)标志位:
        PSH标志位被设置为1时,表示发送方希望接收方尽快交付数据给应用程序,而不进行数据缓冲。
        PSH标志通常用于实时或交互式应用,以减小延迟。
      1. RST(复位)标志位:
        RST标志位被设置为1时,表示发生了错误或异常情况,需要立即终止连接。
        RST标志通常用于恢复连接或中止连接。
      1. SYN标志位(Synchronize):
        当SYN标志位被设置为1时,表示发送方(通常是建立连接的一方)希望建立一个新的TCP连接或发起连接请求。
        当SYN标志位被设置为0时,表示这个数据包不是用于建立连接的请求。
      1. FIN(结束)标志位:
        FIN标志位被设置为1时,表示发送方已经完成了数据的发送,希望关闭连接。
        FIN标志通常用于连接的正常终止,双方都发送FIN来表示不再有数据要发送。
  • 16位检验和:用以确认数据的完整性的,这里的检验和和IP中的检验和是不同的,IP的检验和不会对数据进行计算,而TCP的检验和是包含头部信息和数据一起计算的。

其他信息则不是这么重要,这里不一一介绍了。

3.建立TCP连接:TCP的三次握手

上上图,下图是三次握手的过程:
在这里插入图片描述

  • 第一步:
    客户端首先向服务器发送一个TCP数据包。需要关注TCP首部中的四个数据。
    SYN:设置为1,表示这是一个连接请求,希望建立TCP连接。
    ACK:设置为0,表示不是一个确认请求。
    序号(序列号):可理解为随机生成一串16位数字。
    确认序号(确认序列号):空,确认序号只有在ACK为1时才有效。
  • 第二步:
    服务端收到客户端请求后,回复一个TCP数据包。
    SYN:设置为1,表示这是一个连接请求,希望建立TCP连接,因为TCP是全双工,所以服务端也需要与客户端进行连接。
    ACK:设置为1,表示不是一个确认请求,当前请求既是一个确认请求 也是一个连接请求。
    序号(序列号):可理解为随机生成一串16位数字,每个请求都不同。
    确认序号(确认序列号):第一步序号+1,服务端将这个值给确认序号,客户端收到时就可以知道回复的是哪个请求了。
  • 第三步:
    客户端接收到服务器的响应后,向服务端发送确认请求。
    SYN:设置为0,此时SYN为0,表示不是一个连接请求了。
    ACK:设置为1,表示不是一个确认请求,当前请求只是一个确认请求。
    序号(序列号):空
    确认序号(确认序列号):第二步序号+1,客户端将这第二步的序号+1进行返回,服务端收到ACK为1的报文后,就会解析确认序号以确定当前的ACK是哪个请求的。

这个过程还是很清晰的,TCP经过三次握手后就可以建立一个全双工的通讯了。

为什么必须是三次握手

首先肯定的是三次握手的每一步都是必不可少的,不然TCP是无法建立一个连接的。那为什么必须是三次呢?
必须是三次的原因是因为我们需要建立的是一个双向通讯的连接,双向通讯的连接必须保证客户端需要知道自己的发送能力+接收能力正常,服务端也要知道自己的发送能力+接收能力正常。只要两方都确定了才能建立可靠的连接。而三次握手正好是满足这个的最少握手次数。
第一步+第二步:验证了客户端的发送能力+接收能力正常
第二步+第三步:验证了服务端的发送能力+接收能力正常
所以握手必须是三次,并不能减少任何一次。

4.终止TCP连接:TCP的四次挥手

如果是第一次接触可能会有一个想法,握手可以三次解决为什么挥手不能三次解决呢?因为按照上面的说法我只需要知道客户端和服务端都知道我的连接断了即可。那么三次是可以实现的,为什么需要四次呢?
原因还是因为TCP是一个双向通讯的协议。它支持客户端主动向服务端发送消息,也支持服务端主动向客户端发送消息,同时客户端和服务端的消息发送都是独立的。所以有一个场景必须考虑:客户端如果终止了客户端—>服务端这个链路的连接,那么不能影响服务端—>客户端这个链路的连接,因为客户端并不知道这个链路有没有数据了。所以使用三次握手的模型就不行了,所以有了四次挥手。下图是四次挥手的图解:
在这里插入图片描述

  • 第一步:主动关闭方(通常是客户端)发送一个带有FIN标志位的TCP数据包。
    FIN:设置为1,表示发送方已经完成了数据的发送,希望关闭连接。
    ACK:可能为1,一般客户端处理结束以后给服务端进行ACK时,就会发送FIN,所以这个ACK是可能为1的。
    序号:可以理解为一个16位的随机数。
    确认序号:若是ACK不为1,则不为空
  • 第二步:被动关闭方(通常是服务器)接收到主动关闭方的FIN后对请求方进行响应。
    FIN:设置为0,只是进行响应
    ACK:设置1,对主动关闭方进行响应,所以值为1
    序号:可以理解为一个16位的随机数。
    确认序号:第一步的序号+1,返回后主动关闭方就知道得到别动关闭方的响应了。
  • 第三步:被动关闭方在完成数据传输后,发送一个带有FIN标志位的数据包,这里注意可能最后一次传输和FIN一起发送。
    FIN:设置为1,被动关闭方进行主动关闭请求。
    ACK:可能为1,此时可能随着最后一次的响应发送FIN请求。
    序号:可以理解为一个16位的随机数。
    确认序号:若ACK为1,则不为空。
  • 第四步:
    FIN:设置为0,只是进行响应。
    ACK:设置1,对关闭请求进行响应,所以值为1
    序号:可以理解为一个16位的随机数。
    确认序号:第三步的序号+1,返回后请求关闭方就知道得对方的响应了。

经过这四步,TCP就实现了连接的彻底终止了,之所以是需要4部的根本原因是因为TCP的了连接是全双工的,且双向的通讯属于互不影响的,所以不可以采用三次的模型。

五、传输层 - UDP

UDP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个 UDP数据报,并组装成一份待发送的 IP数据报。
这与面向流字符的协议不同,如 TCP应用程序产生的全体数据与真正发送的单个 IP数据报可能没有什么联系,U D P不提供可靠性:它把应用程序传给 I P层的数据发送出去,但是并不保证它们能到达目的地。
应用程序必须关心 I P数据报的长度。如果它超过网络的 MTU,那么就要对 I P数据报进行分片。
在这里插入图片描述

1.UDP首部

下图是UDP首部的图解:
在这里插入图片描述
可以看到信息并不是很多,如下:
16位源端口号:无论是TCP还是UDP都是使用端口来进行确定程序。
16位目标端口:目标端口号,IP+目标端口方可确定目标程序
16为UDP长度:UDP长度字段指的是UDP首部和UDP数据的字节长度。
16位UDP检验和:UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。UDP的检验和和TCP的类似都是包含首部和数据的,这点和IP的检验和不一致,IP只检验和只包含首部。

2.IP分片

物理网络层一般要限制每次发送数据帧的最大长度。任何时候I P层接收到一份要发送的 IP数据报时,它要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。IP把MTU与数据报长度进行比较,如果需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。
把一份I P数据报分片以后,只有到达目的地才进行重新组装(这里的重新组装与其他网络协议不同,它们要求在下一站就进行进行重新组装,而不是在最终的目的地)。重新组装由目的端的 I P层来完成,其目的是使分片和重新组装过程对运输层( TCP和UDP)是透明的,
除了某些可能的越级操作外。已经分片过的数据报有可能会再次进行分片(可能不止一次)。I P首部中包含的数据为分片和重新组装提供了足够的信息。
一般情况下TCP不会分片,大部分情况下UDP都会有分片。TCP在进行传输时已经对数据进行了切分,所以一般不容易分片。而UDP则是直接传输的,所以容易触发分片。
下图是一个IP分片举例:
在这里插入图片描述

3.UDP协议的实现:DNS

DNS使用的是UDP协议,因为DNS解析要求效率比较高。而UDP的通讯无需建立连接,报文结构相对简单,所以UDP在设计之初就是用来做一些对效率要求比较高的场景。上面已经知道了UDP具有不可靠性,那DNS是如何保证能准确查找到域名对应的IP地址呢?这点其实和TCP有些类似,因为IP本身也是不可靠的,但是TCP通过超时重传、检验和、ICMP等一些列手动实现了稳定可靠的协议。所以针对UDP的不可靠,一般应用层是需要自己提供保证的。

4.域名与多级域名

域名一般分为顶级域名和多级域名。顶级域名也就是一级域名比如通常所看到的.com , .cn 等都是一级域名,而baidu.com的baidu是二级域名。通常情况下大部分人说的二级域名www.baidu.com其实是三级域名。一般购买二级域名以后默认就会拥有下面的三级域名了。

六、应用层HTTP详解

HTTP(Hypertext Transfer Protocol)是一种用于在计算机之间传输超文本文档的协议。它是互联网上最常见的通信协议之一,默认占用端口80

  • 它是一个基于“请求-响应”的模型:
    客户端发送HTTP请求,服务器接收请求并返回HTTP响应;
    在这里插入图片描述

  • 它是一个无状态的协议:
    每个请求和响应都是相互独立的,服务器也不会保存先前请求的状态信息。
    在这里插入图片描述

  • 它使用URI定位资源:
    当客户端请求访问资源而发送请求时,URI 需要将作为请求报文中的请求 URI 包含在内。
    在这里插入图片描述

1.HTTP的报文结构

HTTP是引用层的协议,他和TCP和UDP、IP等也是类似,他也是有首部和报文实体两部分组成。
(HTTP数据叫报文,TCP、UDP数据叫段,IP层数据叫数据报,链路层数据叫帧)
下图是请求报文和响应报文的结构展示,简单清晰:
在这里插入图片描述

  • 请求头
    在这里插入图片描述
    上图是一个请求的请求头信息,下图是标准结构,从上图可以明确看出方法是GET,URI是根路径,HTTP版本是目前使用最广的1.1,在下面就是请求首部字段,比如Host,这个只会在请求头中含有,响应头是不会有的,其他这里就不细说了,后面进行细说。
    在这里插入图片描述

  • 响应头
    下图是一个常见的响应头的头部信息
    在这里插入图片描述
    很明显先是HTTP的版本,然后是状态码和描述,后面就是首部字段了,响应头头的格式如下:
    在这里插入图片描述

2.HTTP首部

上面也看到了HTTP其实就两部分一部分是首部一部分是报文主体,报文主体就是我们需要发送的主体数据了(可以不存在)这个会随着请请求的不同而不同,不过HTTP的首部缺大部分都很类似,但首部却包含了大部分的重要信息在这里HTTP客户端和服务端就是通过首部中声明的一系列信息才能完成正常的通讯,HTTP协议中一共提供了4种首部信息,此外HTTP支持用户进行自定义首部信息(因此我们常常在首部中传递Token),下面看看HTTP支持的首部信息:通用、请求、响应、实体。

首部信息的特点:键值对形式存在大部分的件支持声明多个值多个值使用逗号隔开首部字段不区分大小写,但是建议按规范进行书写(首字母大写)尽量首部字段不要重复(不同服务器对于首部字段处理机制不同,有的是取前面的有的是取后面的)。

2.1 通用首部字段

通用首部字段就是请求和响应都会使用的首部字段

  • Cache-Control : 控制缓存
    顾名思义,这个首部信息就是用来控制缓存的。在应用程序的各层基本都会有缓存机制,通讯协议这块自然也是支持的,这块的缓存是用来指定HTTP的请求是否从缓存中获取等的结果。因为是通用首部所以还区分了请求的指令和响应的指令。下面列举些常用的指令。

    • Cache-Control:public : 响应指令,表示缓存的内容别的用户也可以使用,是共用的缓存
    • Cache-Control:private: 响应指令,只有缓存信息的用户可以使用,其他用户不可以
    • Cache-Control:no-cache: 请求响应指令,不返回过期的资源,缓存服务器需要向服务器进行确认
    • Cache-Control:no-strore: 请求和响应,不缓存
    • Cache-Control:max-age=604800(单位秒):请求指令,若是缓存信息没有超过这个值,则从缓存获取
  • Connection : 连接控制和控制逐跳字段
    Connection不仅可以管理连接的持久性,还可以管理字段是否进行转发,如下所示:
    在这里插入图片描述
    connection被使用最多还是管理连接的持久性,HTTP1.1默认HTTP连接都是持久连接,所以当服务端想要断开连接时需要在头部进行声明 Connection:close . 在HTTP1.1之前,默认是非持久连接的,所以请求和返回都是需要声明Connection:Keep-Alive的,当然现在是不需要了,因为默认就是Connection:Keep-Alive。下图是请求百度时的图片:

    在这里插入图片描述

  • Date:表明创建HTTP报文的日期和时间
    这个则没有什么需要指明的,一般也不需要我们进行设置,所以知道是干什么的字段即可,如果想要设置就需要注意他的日期格式,注意别错了:Date: Tue, 03 Jul 2012 04:40:59 GMT
    在这里插入图片描述

  • Pragma:控制缓存,HTTP1.0及之前的遗留字段
    该字段时遗留字段,虽然放在了通用首部,但是只在请求中使用,是为了向下兼容而保留的,不能排除有的HTTP中间服务器存在HTTP1.1之前的版本,所以该字段进行了保留,该字段的指令可以参考Cache-Control.基本相同。

  • Trailer:说明在报文主体后记录了哪些首部字段
    猛一看会以为没啥用,其实该字段在HTTP/1.1 版本分块传输编码时会使用,如下则表示。在报文主体之后还有首部字段且是Expires
    在这里插入图片描述

  • Transfer-Encoding:规定传输报文主体时采用的编码方式
    在HTTP1.1中仅对分块传输起作用,若不是分块传输使用该首部字段是没有效果的。分块传输:
    在这里插入图片描述

  • Upgrade:用于检测 HTTP 协议及其他协议是否可使用更高的版本
    不过需要注意的是Upgrade只能作用于相邻的HTTP客户服务端,若是有多个中间服务器,第一个服务器之后的是无法传达的,所以一般需要配合Connection:Upgrade来使用,这样就可以保证Upgrade也只会传输到第一个中间服务器了。
    在这里插入图片描述

  • Via:追踪路径使用
    使用Via时,每个中间服务器都会往该字段追加自身的信息,这样服务器端就可以知道调用链路了,反过来从服务器端到客户端也是一样的。
    在这里插入图片描述

  • Warning:告知用户一些与缓存相关的问题的警告
    只有使用缓存时才会有这个警告,他的一般格式如下:
    在这里插入图片描述
    例如如下:
    在这里插入图片描述

2.2 请求首部字段

客户端发送请求时携带,主要是主体内容的补充、请求的客户端信息、告知服务端我的处理能力,比如我只可以接受中文等

  • Accept:通知服务器客户端可以处理的媒体类型
    Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级,一般使用type/subtype(类型/子类型)来进行指定,比如text/html,text/plain。若想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值1,用分号(;)进行分隔。权重值 q 的范围是 0~1(可精确到小数点后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为 q=1.0。
    如:Accept:application/json;q=0.8,application/xml;q=0.2
    常见的文本类型:text/html, text/plain, text/css,application/xml,application/json
    常见的图片类型:image/jpeg, image/gif, image/png
    常见的视频文件:video/mpeg, video/quicktime
    常见的二进制文件:application/octet-stream, application/zip
    下图是百度的例子:
    在这里插入图片描述

  • Accept-Charset:通知服务端客户端可以接受的字符集
    用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段 Accept 相同的是可用权重 q 值来表示相对优先级。比如:Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

  • Accept-Encoding:告诉服务器我可以接受的压缩格式
    用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。比如:Accept-Encoding: gzip, deflate
    下图是百度的:
    在这里插入图片描述

  • Accept-Language:告诉服务器客户端可以处理的自然语言
    比如中文,英文等,同样支持优先级的设置。
    比如:Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3,下图是百度的:
    在这里插入图片描述

  • Authorization:用来传递认证信息
    用来告知服务器请求的认证信息,比如:Authorization: Basic dWVub3NlbjpwYXNzd29yZA==

  • Expect:告知服务器,期望出现的某种特定行为
    告知服务器,期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码 417 Expectation Failed。

  • From:用来指定用户这边负责人的电子邮件,方便联系

  • Host:告知服务器想要请求主机名和端口号
    Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。所以我们可以看到每一个HTTP请你去都是含有Host的。
    注意Host指定的是主机名不是域名和ip,他想要寻找的是目标ip下虚拟主机或者主机名称为其值的目标服务器。这个服务器才是他的目的地。主要是存在同一个ip内被分配了多个域名的情况,此时就需要靠Host来找到对应主机,如果不需要传也可以设置为空。 下面是百度的:
    在这里插入图片描述

  • If-Match

  • If-Modified-Since

  • If-None-Match

  • If-Range

  • If-Unmodiried-Since
    形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。基本很少用到,这里不一一介绍了。

  • Max-Forwards:通故制定一个10进制的数,表示最多经过的转发
    使用一个10进制的数表示最大转发次数,为0时直接返回不会在进行转发。业务场景中该字段不怎么使用,一般是用来探测哪个中间服务器出了问题时来使用。

  • Proxy-Authorization:发送给代理服务器的认证信息
    和Authorization类似,只不过这个认证是发给代理服务器的,而不是服务器

  • Range:告诉服务器需要获取的报文的范文
    比如Range: bytes=5001-10000,表示服务器需要获取的是5001到10000字节的数据

  • Referer:表示请求的URL是从哪个地址发起的
    可能经常会看到Host与Referer比较类似,那是因为我们一般内部系统请求的都是系统内部地址,所以他们的值很是相似。
    有些场景可以使用该字段对来源进行判断,从而做一些白名单。

  • TE:指定传输编码
    注意Accept-Encoding指定的是响应体的编码,这个是传输编码,使用和Accept-Encoding基本相同

  • User-Agent:告诉服务端客户端的信息
    这个字段应该都不会陌生,基本都会存在的,如下是笔者请求百度时的信息:
    在这里插入图片描述

2.3 响应首部字段

补充响应内容,也可能对客户端的发送信息提出要求,客户端可根据要求下次请求进行适配

  • Accept-Ranges:告知客户端,服务端是否可以处理范围请求
    可以处理返回bytes,不可以处理返回none
    Accept-Ranges: bytes
    Accept-Ranges: none
  • Age:告知客户端服务器多久前创建了响应,单位秒
  • ETag:告知客户端服务端资源的标识
    服务端会默认为每个资源分配ETag,这个ETag会在请求信息使用If-Match是进行比较,比较成功才会处理请求。
  • Location:告知客户端请求的资源已被转移,需要访问这个uri。
    基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的URI。几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强制性地尝试对已提示的重定向资源的访问。
  • Proxy-Authenticate:代理要求的认证信息发送给客户端
  • Retry-After:告诉客户端多久后再重试,可以是秒数,也可以是具体的日期
    该字段一般配置5xx的响应码进行使用
  • Server:告知客户端HTTP服务器信息
    比如百度的HTTP服务器:
    在这里插入图片描述
    BWS是百度自建的HTTP服务器,全名Baidu Web Server
  • Vary:服务端告诉代理服务器如何缓存
    从代理服务器接收到源服务器返回包含 Vary 指定项的响应之后,若再要进行缓存,仅对请求中含有相同 Vary 指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于 Vary 指定的首部字段不相同,因此必须要从源服务器重新获取资源。
  • WWW-Authenticate:告诉客户端使用哪种认证方案
    比如:Basic 或是 Digest,一般状态码 401 Unauthorized 响应中,肯定带有首部字段 WWW-Authenticate。

2.4 实体首部字段

实体首部字段就是用来描述报文主体的首部字段,比如时间等,这部分信息主要用来修饰报文体的。这部分头部字段同样是请求头和响应头共用的信息

  • Allow:告知客户端服务端可以处理的方法类型
    比如Allow: Get,Post,当无法处理发送的方法时,会以状态码405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。
  • Content-Encoding:告知客户端服务器对实体的主体部分选用的内容编码方式
    该字段与Accept-Encoding对应,Accept-Encoding指定了客户端可以接受的编码格式,Content-Encoding则表示了实际使用的编码格式,
    如:Content-Encoding: gzip
    在这里插入图片描述
  • Content-Language:告知客户端使用的自然语言
    这个与Accept-Language对应,比如:Content-Language: zh-CN
  • Content-Length:表示主体大小,单位字节
    若实体主体进行内容编码传输时,不能再使用 Content-Length首部字段
  • Content-Location:返回的页面内容与实际请求的对象不同时,用以指明返回的URI
    当返回的页面内容与实际请求的对象不同时,首部字段 Content-Location内会写明 URI。(访问 http://www.hackr.jp/ 返回的对象却是
    http://www.hackr.jp/index-ja.html 等类似情况)
  • Content-MD5:返回主体信息使用MD5进行加密以后的信息
    客户端可以从新对主体使用MD5进行加密,然后比对,就可以判断信息是否有遗失了。
  • Content-Range:告知客户端发送范围
    针对范围请求,返回响应时使用的首部字段 Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。
  • Content-Type:告知客户端主体的媒体类型
    与Accept类似,Accept指明的是可以接受的媒体类型,Content-Type指明的是返回的媒体类型
  • Expires:告知客户端返回资源的失效日期
    将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。
    如果不喜欢缓存,可以将Expires设置成和Date相同的时间
  • Last-Modified:告知客户端资源最后被修改的日期

2.5 非标注首部字段:Cookie

Cookie并不是标准的首部字段,这点可能很多人都有误解,与Cookie相关的首部字段有两个

  • Set-Cookie: 响应首部字段
    告知客户端,服务器开始状态管理了,你可以传递Cookie信息来服务端了。
  • Cookie:请求首部字段
    告知服务器,Cookie信息,可以发送多个Cookie字段

3.HTTP的方法

HTTP将请求类型称为方法,服务端定义通讯方法,客户端请求时必须遵守。下面是HTTP的方法。

  • GET:获取资源
    特点是URL传输数据,数据长度受URL最大长度限制,有安全隐患,不过查询信息一般支持缓存,若是对效率要求比较高,可已使用GET。
  • POST:传输实体主体
    可传输更大量的数据,通常结果不被缓存,信息不在URL传输具有相对更好一些的安全效果
  • PUT:传输文件
    用于传输文件,客户端提供完整的资源数据。
  • HEAD:获得报文首部
    通常用于检查资源的元数据信息,如文件大小。不传输实际数据。
  • DELETE:删除文件
    用于指定删除某些资源,服务器端可能会对该请求方式进行限制
  • OPTIONS:询问支持的方法
    一般用于询问服务器支持的方法,头部信息等,通常在CORS跨域问题时使用,用于检测服务端是否支持跨域,以及支持的跨域的域名端口等。
  • TRACE:追踪路径
    用于问题分析,不常用,用于追踪请求在服务器上的处理轨迹。
  • CONNECT:要求用隧道协议连接代理
    用于建立代理服务器连接,将客户端连接到其他网络服务,如SSL隧道

4.HTTP状态码

状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。下图是状态码的种类:
在这里插入图片描述

  • 200:客户端的请求被处理成功了
  • 204:请求处理成功了,但没有资源可以返回
  • 206:范围请求处理成功:
    该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
  • 301:永久重定向
    该状态码表示请求的资源已被分配了新的 URI,以后应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存
  • 302:临时重定向
    该状态码表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。
  • 303:请使用GET方法访问另一个URL
    与302类似,只不过这里多了一个提示客户端使用GET的意思在里面。
  • 304:请求资源已找到,但条件不满足
    这个状态码好像和重定向没有大关系,表示有资源但你不够资格看
  • 307:临时重定向
    与302相同含义,只是对于请求的转化略有不同,客户端接收到307时不会将POST转GET
  • 400:请求内容无法理解
    表示请求报文存在问题,无法正常处理
  • 401:未认证的请求
    需要传递token等认证信息到服务端才可以
  • 403:不允许访问资源
    可能是权限不足,服务器不会给出明确原因,403就是代表对应资源不给你看
  • 404:URL指定的资源在服务端无法找到
    通常客户端路径错了会提示这个错误
  • 500:内部服务错误
    服务端内部发生异常时,通常直接返回500
  • 503:服务不可用
    503是可以看成比500更高一级的错误,这个错误表示服务不可用了。

5.HTTP的长连接与短连接

HTTP1.1之前每次进行通讯时都是需要先建立连接,通讯结束后断开连接。从HTTP1.1开始默认使用长连接,也就是只要不主动断开,那么连接就会一直存在着。下图是HTTP建立连接和断开连接的简图:
在这里插入图片描述

持久连接,只要有任何一段提出断开连接,连接都会开始进行断开。持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相应提高了。

7.HTTP的压缩传输

HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多的 CPU 等资源。
常见的压缩方式有如下就几种:

  • gzip(GNU zip)
  • compress(UNIX 系统的标准压缩)
  • deflate(zlib)
  • identity(不进行编码)

在这里插入图片描述
需要注意的是压缩的是实体,实体是什么呢?实体是数据的载体,我们常说的报文主体就是存放实体,其实就可以简单理解为传输的内容也可以。

9.HTTP2.0

目前主流的 HTTP/1.1 标准,自 1999 年发布的 RFC2616 之后再未进行过改订。SPDY 和 WebSocket 等技术纷纷出现,很难断言HTTP/1.1
仍是适用于当下的 Web 的协议。下图是HTTP2.0的核心技术,旨在提供更快速的服务。
在这里插入图片描述

七、应用层HTTP的安全版:HTTPS

HTTP协议公开透明,因此HTTP的内容很容易被破解,所以针对内容的安全加密变得需要起来。列举HTTP缺点:

  • 通信使用明文(不加密),内容可能会被窃听
  • 不验证通信方的身份,因此有可能遭遇伪装
  • 无法证明报文的完整性,所以有可能已遭篡改

在这里插入图片描述
为解决这个安全问题,需要对信息进行加密处理。可以通过和 SSL(Secure Socket Layer,安全套接层)或TLS(Transport Layer Security,安全层传输协议)的组合使用,加密 HTTP 的通信内容。
用 SSL建立安全通信线路之后,就可以在这条线路上进行 HTTP通信了。与 SSL组合使用的 HTTP 被称为 HTTPS(HTTPSecure,超文本传输安全协议)或 HTTP over SSL
只对报文主体加密仍有被篡改的风险

1.SSL和TLS

HTTPS 使用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security)这两个协议。TLS是在SSL3.0的基础上研发的,目前使用的较多的是SSL3.0和TLS1.0.因为TLS是在SSL基础上研发的,所以一般说起SSL时可能也是说TLS。
他们都具有以下特点

  • 加密报文
    支持对报文整体信息的加密,不只是对报文主体,而是对所有信息的加密
  • 验明证书
    采用HTTPS通讯时会验证服务端的EV SSL证书,该证书都是由正规合法的证书公司进行办法,用以标识服务端是一个安全可靠的服务。
  • 验证报文完整性
    采用摘要算法对报文进行摘要计算,防止信息被篡改,比如MD5等

2.HTTP+SSL(TLS)=HTTPS

HTTPS默认占用端口443,HTTPS比HTTP慢2-100倍,HTTPS更消耗CPU和内存。此外HTTPS 通信,证书是必不可少的。而使用的证书必须向认
证机构(CA)购买。证书价格可能会根据不同的认证机构略有不同。所以如果没有必要也不用使用HTTPS。下图是HTTP与HTTPS的区别
在这里插入图片描述

3.HTTP的认证

认证就是证明自己是合法用户的过程,HTTP1.1支持的认证如下:

  • BASIC 认证(基本认证)
    这个从HTTP1.0就开始支持的认证方式,即使是现在也有人在用这种认证方式,下图是认证的过程:
    在这里插入图片描述
    假设用户 ID 为 guest,密码是 guest,连接起来就会形成 guest:guest 这样的字符串。然后经过 Base64 编码,最后的结果即是Z3Vlc3Q6Z3Vlc3Q=。把这串字符串写入首部字段 Authorization 后,发送请求。BASIC只是进行了Base64编码,并没有加密,因此这种认证方式安全性不高。当然我们也可以传入token,而不是传入用户名和密码的Base64的编码信息,这样安全性就更高了,不过如果这样不如直接使用头部信息进行传输了。

  • DIGEST 认证(摘要认证)
    HTTP1.1提供了相较于BASIC更为安全的认证方式DIGEST。服务端会告诉客户端传递的参数,其中包含质询码,客户端根据质询码计算响应码response,服务端收到信息进行认证。
    在这里插入图片描述

  • SSL 客户端认证
    这个一般不会有人用,得像服务端那样申请一个证书,证明自己,一般不会有人这么干。

  • FormBase 认证(基于表单认证)
    大部分网站采用的认证方式,基于表单的认证方法并不是在 HTTP 协议中定义的。客户端会向服务器上的 Web 应用程序发送登录信(Credential),按登录信息的验证结果认证。

八、应用层常见的网络攻击

服务端通常来说是为了客户端提供服务,但是总会有一些异常请求进来,比如为了获取用户的隐私信息,为了破坏网站的正常运行等,下面是一些常见的网络攻击方式,在通常的渗透测试中都是由包含的。

1.SQL、OS、XSS(Cross-Site Scripting)

SQL注入、OS注入、XSS是不同的攻击方式,只不过一般服务端都是使用一种方式进行预防的所以就放到一起说了。SQL注入是通过在客户端进行请求时拼接SQL条件从而提升数据的检索返回或者对数据进行修改、删除等操作,从而达到窃取信息和破坏信息的一种目的。
比如我想要查询名称为张三的客户时,这么写:

张三;delete from user;

如果服务端没有进行拦截过滤,就会把对应表信息全不删除。
XSS,则是通过传入脚本对网站进行攻击,可能传入一个js脚本,服务器无法处理进行返回时就会对客户端造成异常响应,通常XSS前端也是需要进行处理的,通过脚本注入前端可以实现绕过服务端直接给客户端进行错误的响应。
OS,一般值传递可以控制系统的命令进行攻击,比如关闭系统。

  • 解决方案
    后端通过增加一个过滤器,对报文主体的信息进行过滤,一般方案是对关键字进行过滤比如:delete、insert、and 、or等等,可以将关键字替换为指定的字符,这样就可以实现攻击的预防了。后端操作可参考:XSSFilter过滤

2.CSFR(Cross-Site Request Forgeries):跨站请求伪造攻击

指攻击者通过设置好的陷阱,获取已经登录的认证信息,然后携带认证信息去操作原认证人的信息,从而达到信息修改的目的。比如一个人刚刚登录了银行网站,此时他又浏览了其他网站信息,此时被获取了他的Cookie信息,然后攻击者携带获取的Cookie进行转账操作,即可成功进行转账。

  • 解决
    一般使用HTTP首部中的Referer信息进行判断请求来源,只有受信任的请求才会被服务端放行,同时服务端可以提供验证操作的机制,即客户端每次请求后都会返回一个随机数给到客户端,客户端下次请求需要携带该随机数,如果没有则拒绝。两种机制一起是可以保证服务的不被CSRF进行攻击的。使用案例可以参考:一文解决CSRF

3.DoS(Denial of Service attack):DoS 攻击

DoS 攻击(Denial of Service attack)是一种让运行中的服务呈停止状态的攻击。有时也叫做服务停止攻击或拒绝服务攻击。DoS 攻击的对象不仅限于 Web 网站,还包括网络设备及服务器等。
主要有以下两种 DoS 攻击方式。

  • 集中利用访问请求造成资源过载,资源用尽的同时,实际上服务也就呈停止状态。
    发送大量的合法请求。服务器很难分辨何为正常请求,何为攻击请求,因此很难防止 DoS 攻击。多台计算机发起的 DoS 攻击称为 DDoS 攻击
    解决:服务端一般采用ip或者用户id进行访问次数控制或操作次数控制,一旦某个ip操作比较频繁可以对这个ip进行流控,使用Hystrix、Sentinel都是可以实现这个控制,当然也可以自己写拦截器进行过滤也是可以的
  • 通过攻击安全漏洞使服务停止。
    这块就要求我们对系统进行足够的安全保护了,所以我们才需要对常见的安全攻击进行预防

九、其他问题

1.CIDR表示法

ip的表示现在有一种常用的CIDR表示法,比如172.16.16.0/24,表示的是24为的网络号,所以他的子网掩码是255.255.255.0,所以这个网段的起始ip是172.16.16.1 ,最大是172.16.16.255 ,注意172.16.16.0 表示网段信息,不可以被分配为ip使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

归去来 兮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值