本文章讲解的内容是计算机网络总结。
基本术语
- 节点(node):在电信网络中,一个节点是一个连接点,表示一个再分发点(redistribution point)或一个通信端点(一些终端设备),节点的定义依赖于网络和协议层,一个物理网络节点是一个连接到网络的有源电子设备,能够通过通信通道发送、接收或转发信息,要注意的是,无源分发点(例如:配线架或接插板)不是节点,在网络理论或图论中,术语节点表示网络拓扑中,线相交或分支的点。
- 链路(link):从一个节点到另一个节点的一段物理线路,要注意的是,中间不能有其他的交点。
- 主机(host):连接在因特网上的计算机。
- 分组(packet):因特网中传送的数据单元,又称为包,它由首部(header)和数据段组成,首部也称为包头。
- 存储转发(Store And Forward):以太网交换机的控制器先将输入端口到来的数据包缓存起来,先检查数据包是否正确,并过滤掉冲突包错误,确定包正确后,取出目的地址,通过查找表找到想要发送的输出端口地址,然后将该包发送出去。
- 带宽(bandwidth):信号所占据的频带宽度,在被用来描述信道时,它是指能够有效通过该信道的信号的最大频带宽度,对于模拟信号而言,带宽又称为频宽,以赫兹(Hz)为单位。
- 吞吐量(throughput):表示在单位时间内通过某个网络节点的数据量,它的单位通常表示为比特每秒(bit/s或bps),有时也可以看到数据包每秒或数据包每时隙等单位。
- ISP(Internet Service Provider):它又称因特网服务提供者、互联网服务提供者、网络服务供应商,是指提供互联网存取服务的公司。
- IXP(Internet Exchange Point):它称为互联网交换中心,是物理基础架构,互联网服务供应商(ISP)和内容传递网络(CDN)通过它们在自治系统之间交换互联网流量。
- RFC(Request For Comments):请求协议,它包括了Internet几乎所有的文字资料。
- 广域网(Wide Area Network,简称WAN):它又称外网和公网,是连接不同地区局域网或者城域网计算机通讯的远程网,通常跨接很大的物理范围,所覆盖的范围从几十公里到几千公里,它能连接多个地区、城市和国家,甚至横跨几个洲提供远距离通信,形成国际性的远程网络,要注意的是,广域网不等同于互联网。
- 城域网(Metropolitian Area Network,简称MAN):它是指大型的计算机网络,属于IEEE802.6标准,是介于LAN和WAN之间能传输语音和资料的公用网络,改进了LAN中传输介质,扩大局域网的范围,达到一个大学校园、城市或者都会区。
- 局域网(Local Area Network,简称LAN):它是连接住宅、学校、实验室、大学校园或者办公大楼等有限区域内计算机的计算机网络,在历经使用了链式局域网、令牌环和AppleTalk技术之后,以太网和Wi-Fi(无线网络连接)是现今局域网最常用的两项技术。
- 个人局域网(Personal Area Network,简称PAN):它是指个人范围(随身携带或数米之内)的计算设备(例如:计算机、电话、PDA或者数字相机等)组成的通信网络;它可以用于设备之间互相交换数据,也可以用于连接到高层网络或互联网;它可以使有线的形式,例如:USB或者Firewire(IEEE1394)总线,也可以是无线的形式,例如:红外(IrDA)或蓝牙,采用无线技术的个人局域网,称为无线个人局域网(Wireless Personal Area Network,简称WPAN)。
OSI模型
开放式系统互联模型(Open System Interconnection Model,简称OSI模型)是一种概念模型,由国际标准化组织提出,是一种试图使各种计算机在世界范围内互连为网络的标准框架,它在1984年定义于ISO/IEC 7498-1标准。
OSI模型将计算机网络体系结构分为七层,其中第一层在底部,第七层在顶部:
- 物理层(Physical Layer):在局部局域网上传送数据帧(Data Frame),它负责管理电脑通信设备和网络媒体之间的互通,例如:以太网、调制解调器、电力线通信、同步光网络、G.709、光导纤维、同轴电缆和双绞线等。
- 数据链路层(Data Link Layer):负责网络寻址、错误侦测和改错。当表头和表尾被加至数据包时,会形成信息框(Data Frame)。数据链表头(DLH)是包含了物理地址、错误侦测和改错的方法;数据链表尾(DLT)是一串指示数据包末端的字符串,例如:WiFi(IEEE 802.11)、ARP、WiMAX(IEEE 802.16)、ATM、DTM、令牌环、以太网、FDDI、帧中继、GPRS、EV-DO、HSPA、HDLC、PPP、PPPoE、L2TP、ISDN、SPB和STP等。
- 网络层(Network Layer):决定数据的路径选择和转寄,把网络表头(NH)加到数据包形成报文。网络表头包含了网络资料,例如:IP(v4和v6)、ICMP(v8)、IGMP、IS-IS、IPsec、BGP、RIP、OSPF和RARP等。
- 传输层(Transport Layer):把传输表头(TH)加到数据形成数据包。传输表头包含所使用的协议等发送消息,例如:TCP(T/TCP和Fast Open)、UDP、DCCP、SCTP、RSVP、PPTP和TLS/SSL等。
- 会话层(Session Layer):负责在数据传输中设置和维护计算机网络中两台计算机之间的通信连接,该层被弃用,应用层的HTTP、PRC、SDP和RTCP等协议有类似的功能。
- 表示层(Presentation Layer):把数据转换为能与接受者的系统格式兼容并适合传输的格式,该层被弃用,应用层的HTTP、FTP和Telnet等协议有类似的功能,传输层的TLS/SSL也有类似的功能。
- 应用层(Application Layer):提供为应用软件而设的接口,来设置与另一个应用软件之间的通信,例如:DHCP(v6)、DNS、FTP、Gopher、HTTP(SPDY和HTTP/2)、IMAP4、IRC、NNTP、XMPP、POP3、SIP、SMIP、SNMP、SSH、TELNET、RPC、RTSP、SDP、SOAP、GTP、STUN、NTP和SSDP等。
TCP/IP
互联网协议套件(Internet Protocol Suite,简称IPS)是一个网络通信模型,以及一整个网络传输协议家族,为网际网络的基础通讯架构,又称为TCP/IP协议族(TCP/IP Protocol Suite或TCP/IP Protocols),简称TCP/IP,该协议家族涉及到两个重要的核心协议:TCP(传输控制协议)和IP(网际协议)。
TCP
传输控制协议(Transmission Control Protocol,简称TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义,位于OSI模型的传输层。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制),然后TCP把结果包传给IP层,由它来透过网络将包传送到接收端实体的TCP层,TCP为了保证不发生丢包,会给每一个包一个序号,同时序号也可以保证传送到接收端实体的包按序接收,然后接收端实体对已成功收到的包发回一个相应的确认消息(ACK),如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失并进行重传。
TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。
数据在TCP层称为流(Stream),数据分组称为分段(Segment),作为比较,数据在IP层称为数据报(Datagram),数据分组称为分片(Fragment),UDP(用户数据报协议)中的数据分组称为消息(Message)。
运作方式
TCP协议的运行可以分为三个阶段:连接创建(Connection Establishment)、数据传输(Data Transfer)、连接终止(Connection Termination)。
操作系统将TCP连接抽象为套接字(Socket)表示的本地端口(Local End-Point),作为编程接口给程序使用,在TCP连接的生命期内,本地端口要经历一系列的状态改变。
连接创建
TCP用三次握手(three-way handshake,又称为三路握手)过程创建一个连接。在连接创建的过程中,很多参数都要被初始化,例如:序号被初始化,它可以保证按序传输和连接的强壮性。
一对终端同时初始化一个它们之间的连接是可能的,但是通常是由一端(服务器端)打开一个套接字(Socket)然后监控来自另一端(客户端)的连接,这个称为被动打开(passive open),服务器端被被动打开以后,客户端就能开始创建主动打开(active open)。
服务器端执行listen函数后,就在服务器上创建两个队列:
- SYN队列:存放完成了二次握手的结果,队列的长度由listen函数的参数backlog指定。
- ACCEPT队列:存放完成了三次握手的结果,队列的长度由listen函数的参数backlog指定。
三次握手过程
- 客户端处于Closed状态,服务端处于Listen状态,客户端调用connect函数向服务端发送一个SYN包,并且指定客户端的初始化序号ISN(c),请求一个主动打开(active open),这个时候客户端处于SYN_SENT状态;首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但是会消耗掉一个序号。
- 服务器端收到客户端发送的SYN包后,把这个包放入SYN队列中,并且回送一个SYN/ACK包,指定服务端的初始化序号ISN(s),同时会把客户端的ISN再加上1,也就是ISN+1作为ACK的值,这个时候服务器处于SYN_RCVD状态;在确认报文段中,SYN=1、ACK=1,确认号ack=x+1,初始序号seq=y。
- 客户端收到SYN/ACK包后,发送一个ACK包,把服务端的ISN再加上1作为ACK的值,这个时候客户端处于ESTABLISHED状态,然后客户端的connect函数成功返回,当服务端接受到这个ACK包的时候,把请求帧从SYN队列中移出,放到ACCEPT队列中,这个时候如果accept函数处于阻塞状态,就可以被唤醒,从ACCEPT队列中取出ACK包,重新创建一个新的用于双向通信的sockfd,并且返回,这个时候服务端处于ESTABLISHED状态,双方已建立起连接;确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始是seq=x,因为是第二个报文,所以要加上1),要注意的是,ACK报文段可以携带数据,如果不携带数据就不消耗序号。
发送第一个SYN包的一端执行主动打开(active open),接收这个SYN包并且发回下一个SYN包的另一端执行被动打开(passive open)。
在Socket编程中,客户端调用connect函数触发三次握手。
要注意的是,如果服务器端接收到了客户端发的SYN包后,回送SYN/ACK包的时候掉线,服务器端没有收到客户端回送的ACK包,这个时候该连接就处于一个中间状态(既没有成功,也没有失败),服务器端如果在一定时间内重发SYN/ACK包,在Linux下,默认重试次数是五次,重试的间隔时间从一秒开始每次都翻倍,例如:五次的重试时间间隔是1秒、2秒、4秒、8秒、16秒,总共需要1秒+2秒+4秒+8秒+16秒=31秒的时间,第五次发出后还要等32秒才知道第五次超时,也就是说,总共需要1秒+2秒+4秒+8秒+16秒+32秒=63秒的时间,TCP才会断开这个连接,可以使用三个TCP参数来调整行为:
- tcp_synack_retries:减少重试次数。
- tcp_max_syn_backlog:增大SYN连接数。
- tcp_abort_on_overflow:决定超出能力时的行为。
资源使用
主机收到一个收到一个TCP包的时候,用两端的IP地址与端口号来标识这个TCP包属于哪个session,使用一张表来存储所有的session,表中每条称作Transmission Control Block(TCB),TCB结构的定义包括连接使用的源端口、目的端口、目的IP、序号、应答序号、对方窗口大小、己方窗口大小、TCP状态、TCP输入/输出队列、应用层输出队列和TCP的重传有关变量等。
服务器端的连接数量是无限的,只会受到内存限制;客户端的连接数量,在以前由于发送第一个SYN包到服务器之前需要先分配一个随机空闲的端口,这限制了客户端IP地址的对外发出连接的数量上限,从Linux 4.2开始,有了Socket选项IP_BIND_ADDRESS_NO_PORT,它通知Linux内核不保留usingbind使用端口号为0时内部使用的临时端口(Ephemeral Port),在connect时会自动选择端口以组成独一无二的四元组(同一个客户端端口可用于连接不同服务器套接字,同一个服务器端口可用于接受不同客户端套接字的连接)。
要注意的是,对于不能确认的包、接收单还没读取的数据,都会占用的操作系统的资源。
数据传输
在TCP的数据传输状态,可以使用以下机制保证TCP的可靠性和强壮性:
- 使用序号,对收到的TCP报文段进行排序以及检测重复的数据。
- 使用校验和检测报文段的错误,也就是无错传输。
- 使用确认和计时器来检测和纠正丢包或延时。
- 流控制(Flow Control)。
- 拥塞控制(Congestion Control)。
- 丢失包的重试。
连接终止
TCP用四次握手(four-way handshake,又称为四路握手、四次挥手)过程终结一个连接。
四次握手过程
- 客户端发出一个FIN报文,并且指定一个序号,发出连接释放报文段(FIN=1,序号seq=u),并且停止发送数据,主动关闭TCP连接,这个时候客户端处于FIN_WAIT1(终止等待1)状态,等待服务端确认。
- 服务端收到FIN报文后,会发送ACK报文,把客户端的序号再加上1作为ACK报文的序号值,这个确认报文段是ACK=1,确认号ack=u+1,序号seq=v,表示已经收到客户端的报文,这个时候服务端处于CLOSE_WAIT(关闭等待)状态,这个时候TCP处于半关闭状态,等待服务端发出的连接释放报文段。
- 如果服务端也想断开连接,服务端发出FIN报文,并且指定一个序号,发出连续释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),这个时候服务端进入LAST_ACK(最后确认)状态,等待客户端确认。
- 客户端收到FIN报文后,会发送一个ACK报文作为应答,把服务端的序号加上1作为ACK报文的序号值,发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态,这个时候TCP未释放掉,需要经过时间等待计时器设置的时间2倍的MSL后客户端才进入CLOSED(关闭)状态。
MSL(Maximum Segment Lifetime)是指报文段最大生存时间,每个具体TCP实现必须选择一个MSL,它是任何报文被丢弃前在网络内的最长时间,这个时间是有限的,因为TCP报文段是以IP数据报在网络内传输,而IP数据报是有限制其生存时间的TTL字段,
客户端通常执行主动关闭(active open),并且进入TIME_WAIT(时间等待)状态;服务端通常执行被动关闭(passive close),但是不会进入TIME_WAIT(时间等待)状态。
在Socket编程中,任何一方调用close函数都可以触发四次握手。
IP
网际协议(Internet Protocol,简称IP,又称为互联网协议),是用于分组交换数据网络的协议。
为了根据源主机和目的主机的地址来传送数据,IP定义了寻址方法和数据报的封装结构,第一个架构的主要版本为IPv4,目前仍然是广泛使用的互联网协议,不过世界各地正在积极部署IPv6。
UDP
用户数据报协议(User Datagram Protocol,简称UDP,又称为用户数据报协议)是一种简单的面向数据报的通信协议,位于OSI模型的传输层,该协议由David P. Reed在1980年设计且在RFC 768中规范。
在TCP/IP模型中,UDP为网络层以上和应用层以下提供了一个简单的接口。
UDP只提供数据的不可靠传输,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份,所以UDP被认为是不可靠的数据报协议,要注意的是,UDP在IP数据报的头部仅仅加入了复用和数据校验字段。
UDP适用于不需要或者在程序中执行错误检查和纠正的应用,它避免了协议栈中此类处理的开销,对时间有较高要求的应用程序通常使用UDP,因为丢弃数据包比等待或者重传导致延迟更可取。
ARP
地址解析协议(Address Resolution Protocol,简称ARP)是一个通过解析网络层地址来寻找数据链路层地址的网络传输协议,它在IPv4中极其重要,最初在1982年的RFC 826中提出纳入互联网标准STD 37。
ARP是通过网络地址来定位MAC地址,它已经在很多网络层和数据链路层之间得以实现,包括IPv4、Chaosnet、DECnet和Xerox PARC Universal Packet(PUP)使用IEEE 802标准,光纤分布式数据接口、X.25、帧中继和异步传输模式(ATM)、IEEE 802.3和IEEE 802.11标准中IPv4占了多数流量。
在IPv6中邻居发现协议(NDP)用于代替ARP。
NDP
邻居发现协议(Neighbor Discovery Protocol,简称NDP或者ND)是TCP/IP协议栈的一部分,用于IPv6,它工作在数据链路层,负责链路上发现其他节点和相应的IP地址,并且确定可用路由和维护关于可用路径和其他活动节点的信息可达性。
统一资源标识符
统一资源标识符(Uniform Resource Identifier,缩写:URI)用于标识某一互联网资源名称的字符串,这种标识允许用户对网络(一般指万维网)中的资源通过特定的协议进行交互操作。
统一资源定位符(Uniform Resource Locator,缩写:URL)和统一资源名称(Uniform Resource Name,缩写:URN)都属于URI的子类,URI可以为URL和URN两者之一或者同时是URI和URN。
统一资源定位符的标准格式如下所示:
[协议类型]://[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
统一资源定位符的完整格式如下所示:
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]
要注意的是,[访问资源需要的凭证信息]、[端口号] 、[查询]、[片段ID]都属于选填项。
HTTP
HTTP(HyperText Transfer Protocol)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。通过HTTP协议或者HTTPS协议请求的资源由统一资源标识符(Uniform Resouce Identifiers,简称URI)来标识。设计HTTP的最初目的是为了提供一种发布和接收HTML页面的方法。
HTTP是一个客户端(用户)和服务端(网站)之间请求和应答的标准,通常使用TCP协议。
尽管TCP/IP协议是互联网上最流行的应用,但是在HTTP协议中并没有规定它必须使用或者它支持的层,事实上HTTP可以在任何互联网协议或者其他网络上实现。HTTP假定其下层协议提供可靠的传输,因此任何能够提供这种保证的协议都可以被其使用,所以HTTP在TCP/IP协议族使用TCP作为其传输层。
通常,由HTTP客户端发起一个请求,创建一个到服务器指定的端口(默认是80端口)的TCP连接,HTTP服务器则在那个端口监听客户端的请求,一旦收到请求,服务器会向客户端返回一个状态,例如:HTTP/1.1 200 OK和返回的内容,例如:请求的文件、错误信息和其它信息。
相关的协议
HTTP是属于应用层的协议,但是它还需要使用其他层的协议配合来完成信息的交换,涉及到如下的协议:
版本
- HTTP/0.9:只接受GET一种请求方法,没有在通讯中指定版本号,而且不支持请求头,这个版本已经过时。
- HTTP/1.0:这是第一个在通讯中指定版本号的版本。
- HTTP/1.1:默认采用持续链接(Connection:keep-alive),可以很好地配合代理服务器工作,还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
- HTTP/2:超文本传输协议第二版,简称为h2(基于TLS/1.2或以上版本的加密连接)或者h2c(非加密连接)
HTTP/1.1相较于HTTP/1.0的区别主要体现在如下:
- 缓存处理
- 带宽优化和网络连接的使用
- 错误通知的管理
- 消息在网络中的发送
- 互联网地址的维护
- 安全性和完整性
HTTP/2
HTTP/2是超文本传输协议第二版,简称h2(基于TLS/1.2或以上版本的加密连接)或者h2c(非加密连接),是HTTP协议的第二个主要版本,在万维网使用。
HTTP/2是HTTP协议自1999年HTTP/1.1发布后的首个更新,主要基于SPDY协议,它由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组进行开发,该组织于2015年5月以RFC 7540正式发表,HTTP/2的标准化工作由Chrome、Opera、Firefox、Internet Explorer 11、Safari、Amazon Silk和Edge等浏览器提供支持。
二进制分帧
HTTP/2采用二进制格式传输数据,而不是HTTP/1.x的文本格式,解析起来会更加高效。
有两个概念:
- 帧:HTTP/2数据通信的最小单位消息,例如:请求和响应等消息由一个帧或者多个帧组成。
- 流:它可以承载双向信息,每个流都一个唯一的整数ID,存在于连接中的一个虚拟通道。
HTTP/1.x的请求报文和响应报文,都是由起始行(start line)、头部字段(header)、消息正文(entity)组成,各部分之间以文本换行符分隔,而HTTP/2将请求数据和响应数据分割为更小的帧,并且采用二进制编码。
在HTTP/2中,同一个域名下所有通信都在单个连接上完成,这个连接可以承载任意数量的双向数据流,每个数据流都是以消息的形式发送,消息是由一个或者多个帧组成,多个帧可以乱序发送,根据帧首部的流标识可以重新组装。
多路复用
在HTTP/1.x中,如果想并发多个请求,就必须使用多个TCP链接,而且浏览器为了控制资源,还会对单个域名有6~8个的TCP链接请求限制;在HTTP/2中,因为存在二进制分帧,所以不再依赖TCP链接去实现多流并行,有如下特性:
- 同一个域名的所有通信都在单个连接上完成,只占用一个TCP连接,消除多个TCP连接带来的延迟和内存消耗。
- 单个连接承载任意数量的双向数据流,可以并行交错的请求和响应,之间互不干扰。
- 每个请求可以带一个31bit的优先值,0表示最高优先级,数值越大优先级越低,客户端和服务端通过优先值可以在处理不同的流时,采取不同的策略,数据流以消息的形式,消息又是由一个或者多个帧组成,多个帧之间可以乱序发送,原因是可以根据帧首部的流标识重新组装。
服务器推送
服务端可以在发送页面HTML时主动推送其它资源,而不需要等待浏览器解析到相应位置,例如:服务端可以主动把JS文件和CSS文件推送给客户端,而不需要等待客户端解析HTML时再发送这些请求。
客户端可以选择是否接收,如果服务端推送的资源已经被浏览器缓存过,浏览器可以发送RST_STREAM帧来拒收。
主动推送遵守同源策略,服务器不会随便推送第三方资源给客户端。
头部压缩
HTTP每次通信,都会携带一组头部,用于描述这次通信的资源、浏览器属性,在HTTP/1.x中,因为需要等待带着ACK的响应回来以后才能继续发送请求,所以会导致请求的大小越来越大,有时候甚至大于TCP窗口的初始大小,而且携带大量冗余头部消息,浪费带宽资源;在HTTP/2中,它会对消息头采用HPACK(专门为HTTP/2头部设计的压缩格式)进行压缩传输,节省消息头占用的网络流量。
压缩策略是在客户端和服务端使用首部表来跟踪和存储之前发送的键值对,对于相同的数据,不再每次通过请求和响应发送,首部表在连续存续期内始终存在,它是由客户端和服务端共同渐进地更新,每个新的键值对有可能会追加到这个首部表的的末尾,也有可能替换这个首部表之前的值。
报文
HTTP协议的报文分为请求报文和响应报文,它们由三大部分组成:
- 起始行(start line):描述请求或者响应的基本信息。
- 头部字段(header):使用键值对的形式描述报文。
- 消息正文(entity):描述实际传输的数据,可以使纯文本,也可以是图片或视频等二进制数据。
起始行(start line)和头部字段(header)并称为请求头或者响应头,也称为Header,消息正文(entity)称为实体,也称为Body,要注意的是,HTTP协议规定每次发送必须由Header,但是可以没有Body,Header和Body之间必须要有一个空行(CRLF),例子如下:
可以看到报文是用ASCII文本书写的,每一行之间都存在换行,最后一行会加上一个回车换行符。
请求方法
HTTP协议请求方法分为九种,如下所示:
- GET:请求访问已被URI识别的资源,指定的资源经过服务端解析后返回响应内容。
- HEAD:获得响应头部,它类似于GET请求,只是不返回报文主体部分,用来确认URI的有效性和资源的更新日期等。
- POST:向指定资源提交要处理的数据,数据被包含在请求体中,用来提交表单或者上传文件。
- PUT:从客户端向服务端传输数据取代指定的资源内容。
- DELETE:请求服务端删除指定的资源。
- CONNECT:要求与代理服务端通信时建立隧道,实现用隧道(Tunneling Protocol)协议进行TCP通信,主要使用SSL(Secure Sockets Layer,称为安全套接字)协议和TLS(Transport Layer Security,称为传输层安全性)协议对通信内容加密后经过隧道传输。
- OPTIONS:允许客户端查看服务端的性能,可以用来查询针对请求URI指定的资源支持的方法。
- TRACE:回显服务器收到的请求,用于测试或者诊断。
- PATCH:对PUT请求的补充,用来对已知资源进行局部更新。
要注意的是,HTTP/1.0定义三种请求方法:GET请求、HEAD方法和POST请求;HTTP/1.1新增六种请求方法:PUT请求、DELETE请求、CONNECT请求、OPTIONS请求、TRACE请求和PATCH请求。
头字段
HTTP头字段(HTTP header fields)是指在超文本传输协议(HTTP)的请求(request)和响应(response)消息中的消息头部分
基本格式
HTTP头字段是在请求行或者响应行之后传输的,这些字段是以明文的字符串格式传输,它一个键值对,以冒号分隔键名和键值,以回车(CR)加上换行(LF)符号序列结尾。
类型
HTTP头字段根据实际用途分为以下四种类型:
- 通用头字段(General Header Fields)
- 请求头字段(Request Header Fields)
- 响应头字段(Response Header Fields)
- 实体头字段(Entity Header Fields)
通用头字段
-
Cache-Control:指向从服务端直到客户端在内的所有的缓存机制告知,它们是否可以缓存这个对象,它的单位是秒,它可以出现在请求标头和响应标头中,例子如下所示:
Cache-Control: no-cache
-
Connection:决定当前事务(三次握手和四次挥手)完成后,是否关闭网络连接,例子如下所示:
Connection: keep-alive Connection: Upgrade
-
Date:指这条消息发送时的日期和时间(按照RFC 7231中定义的“超文本传输协议日期”格式来表示),它可以出现在请求标头和响应标头中,例子如下所示:
Date: Mon, 8 Mar 2021 03:00:00 GMT
-
Pragma:指报文指令,例子如下所示:
Pragma: no-cache
-
Trailer:指报文末端的首部一览,例子如下所示:
Trailer: Max-Forwards
-
Transfer-Encoding:指定报文主体的传输编码格式,例子如下所示:
Transfer-Encoding: chunked
-
Upgrade:用来升级为其他协议,例子如下所示:
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
-
Via:指代理服务器的相关信息,例子如下所示:
Via: 1.0 fred, 1.1 p.example.net
-
Warning:指错误通知,例子如下所示:
Warning: 199 Miscellaneous warning
请求头字段
- Accept:告知服务端能够接受回应内容类型(Content-Types)。
- Accept-Charset:告知服务端能够接受的字符集。
- Accept-Encoding:告知服务端发送的编码格式,例如:gzip、deflate。
- Accept-Language:告知服务端能够发送的语言。
- Authorization:提供信息给服务端对其身份认证。
- Except:指要求服务端做出特定的行为。
- From:提供客户端的Email地址。
- Host:提供接受请求的服务端的主机号和端口号,要注意的是,如果所请求的端口是对应服务的标准端口,那么端口号可以忽略。
- If-Match:字段值与服务端特定字段标记值(ETag)匹配才处理请求。
- If-Modified-Since:确认本地资源是否有效,如果是有更新,就处理请求,否则响应返回状态码304 Not Modified。
- If-None-Match:字段值与服务端特定字段标记值(ETag)不匹配才处理请求,与If-Match相反。
- If-Range:对资源的某个范围请求。
- If-Unmodified-Since:确认本地资源是否有效,如果没有更新,就处理请求,否则响应返回状态码412 Precondition Failed。
- Max-Forwards:限制代理或者网关转发次数。
- Proxy-Authorization:提供信息给服务端对代理进行身份认证。
- Range:获取部分资源。
- Referer:当前文档的URL。
- TE:告知服务端可以使用的扩展传输编码。
- User-Agent:发出请求的应用程序名称。
实体头字段
- Allow:告知客户端对特定资源能使用的HTTP方法,当服务端收到不支持的方法请求时,会返回状态码405 Method Not Allow。
- Content-Encoding:告知客户端要用的的解压方式,用于对特定的媒体类型数据进行压缩
- Content-Length:以八位字节数组表示的请求体的长度。
- Content-Type:指请求体的多媒体类型(用于POST请求和PUT请求)。
- Expires:指定日期或者时间,如果超过,就表示已过期,要注意的是,如果Cache-Control设置了max-age和s-max-age,那么这个字段就会被忽略。
- Last-Modified:所请求的对象的最后修改日期(按照RFC 7231中定义的超文本传输协议日期格式来表示)。
常见非标住字段
-
X-Frame-Options:用于防止点击劫持(clickjacking),如下所示:
- deny:该页面不允许在frame中展示,即使是同域名内。
- sameorigin:该页面允许同域名内在frame中展示。
- allow-from uri:该页面允许在指定uri的frame中展示。
- allowall:允许任意位置的frame显示,非标准值。
- X-XSS-Protection:控制浏览器XXS防护机制开关,0代表关闭XSS过滤,1代表开启XSS过滤。
- DNT:请求某个网页应用程序停止跟踪某个用户,要注意的是,在火狐浏览器中,相当于X-Do-Not-Track协议头字段(自Firefox/4.0 Beta 11版开始支持),0代表禁用DNT,1代表启用DNT。
状态码
HTTP状态码(HTTP Status Code)是用来表示网页服务器超文本传输协议响应状态的三位数字代码,它由RFC 2616规范定义的,并得到RFC 2518、RFC 2817、REC 2295、RFC 2774和RFC 4918等规范扩展。
HTTP状态码分为五种状态,分别为消息、成功、重定向、客户端错误和服务器错误,如下所示:
1XX消息
1XX类型的状态码代表请求已被接受,需要继续处理,要注意的是,这类响应是临时响应,只包含状态行和某些可选的响应头信息,并且以空行结束。
100 Continue
表示服务端已经接受到请求头,并且客户端应该继续发送请求主体(例如:POST请求),如果请求已经完成,就会忽略这个响应。
101 Switching Protocols
表示服务端已经理解客户端的请求,并且将通过Upgrade消息头通知客户端采用不同的协议完成这个请求。
102 Processing(WebDAV、RFC 2518)
表示服务端已经收到并且正在处理请求,但是无响应可用,要注意的是,WebDAV请求可能包含许多涉及文件操作的子请求,需要很长时间才能完成请求。
103 Early Hints(RFC 8297)
表示在最终的HTTP消息之前返回一些响应头字段。
2XX成功
2XX类型的状态码代表请求已成功被服务端接收、理解、并且接受。
200 OK
表示请求已成功,请求所希望的响应头字段或者数据体将随此响应返回。
201 Created
表示请求已经被实现,而且有一个新的资源已经依据请求的需要而创建,并且其URI已经随Location头消息返回。
202 Accepted
表示服务器已接受请求,但是尚未处理。
203 Non-Authoritative Information(自HTTP/1.1起)
服务器是一个转换代理服务器(Transforming Proxy),例如:网络加速器,它是以状态码200为起源,但是回应了原始响应的修改版本。
204 No Content
服务器成功处理请求,但是没有返回任何内容。
205 Reset Content
服务器成功处理请求,但是没有返回任何内容,与状态码204不相同的地方是这个响应要求请求者重置文档视图。
206 Partial Content(RFC 7233)
服务器成功处理部分GET请求。
207 Multi-Status(WebDAV、RFC 4918)
表示之后的消息体是一个XML消息,并且可能根据之前子请求数量的不同,包含一系列独立的响应代码。
208 Already Reported(WebDAV、RFC 5842)
DAV绑定的成员已经在多状态响应之前的部分被列举,并且未被再次包含。
226 IM Used(RFC 3229)
服务器已经满足了对资源的请求,对实体请求的一个或者多个实体操作的结果表示。
3XX重定向
3XX类型的状态码代表客户端采取进一步的操作才能完成请求。通常这类型的状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。
300 Multiple Choices
被请求的资源有一系列可供选择的回馈消息,每个都有自己特定的地址和浏览器驱动的商议信息,用户或者浏览器能够自行选择一个首选的地址进行重定向。
301 Moved Permanently
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一,如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务端反馈回来的地址,除非额外指定,否则这个响应也是可缓存的。
302 Found
要求客户端执行临时重定向(Moved Temporarily),由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求,只有在Cache-Control或者Expires中进行了指定的情况下,这个响应才是可缓存的。
303 See Other
对应当前请求的响应可以在另一个URI上被找到,当响应于POST请求、PUT请求或者DELETE请求接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的GET请求消息发出重定向。
304 NotModified
表示资源在由请求头字段中的If-Modified-Since或If-None-Match参数指定的这一版本之后,未曾被修改,在这种情况下,由于客户端仍然具有以前下载的副本,因此不需要重新传输资源。
305 Use Proxy
被请求的资源必须在指定的代理才能被访问。
306 Switch Proxy
后续请求应使用指定的代理,要注意的是,在最新版的规范中,这个状态码不再被使用。
307 Temporary Redirect
请求应该与另一个URI重复,但后续的请求应仍使用原始的URI, 与状态码302相反,当重新发出原始请求时,不允许更改请求方法,例如:应该使用另一个POST请求来重复POST请求。
308 Permanent Redirect(RFC 7538)
请求和所有将来的请求应该使用另一个URL重复。
4XX客户端错误
4XX类型的状态码代表客户端可能发生了错误,妨碍了服务器处理。
400 Bad Request
由于客户端明显的错误(例如:请求语法错误、大小太大、无效的请求或者欺骗性路由请求),服务端不能或不会处理处理该请求。
401 Unauthorized(RFC 7235)
语义是指未认证,即用户没有必要的凭证,表示当前请求需要用户验证。
402 Payment Required
最初的意图是可能被用作某种形式的数字现金或者在线支付方案的一部分,但是几乎没有哪家服务商使用,而且这个状态码通常不被使用。
403 Forbidden
服务端已经理解请求,但是拒绝执行它,与状态码401不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。
404 Not Found
请求失败,请求所希望得到的资源未被在服务端上发现,但是允许用户的后续请求。
405 Method Not Allowed
请求行中指定的请求方法不能被用于请求相应的资源,该响应必须返回一个Allow头信息用以表示出当前资源能够接受的请求方法的列表。
406 Not Acceptable
请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体,该请求不可接受。
407 Proxy Authentication Required(RFC 2617)
与状态码401类似,只不过客户端必须在代理服务器上进行身份验证,代理服务器必须返回一个Proxy-Authenticate用来进行身份验证,客户端可以返回一个Proxy-Authorization信息头用来验证。
408 Request Timeout
请求超时,客户端没有在服务端预备等待的时间内完成一个请求的发送,客户端可以随时再次提交这一请求而无需进行任何更改。
409 Conflict
表示因为请求存在冲突无法处理该请求,例如:多个同步更新之间的编辑冲突。
410 Gone
表示所请求的资源不再可用,当资源被有意地删除并且资源应该被清除的时候,应该使用该状态码。
411 Length Required
服务端拒绝在在没有定义Content-Length头字段的情况下接受请求。
412 Precondition Failed(RFC 7232)
服务端在验证请求的头字段中给出先决条件时,没能够满足其中的一个或者多个;这个状态码允许客户端在获取资源的时候在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。
413 Request Entity Too Large(RFC 7231)
表示服务端拒绝处理当前请求,因为该请求提交的实体数据大小超过服务端愿意或者能够处理的范围,在这种情况下,服务端可以关闭连接以免客户端继续发送该请求。
414 Request-URI Too Long(RFC 7231)
表示请求的URI长度超过服务端能够理解的长度,因此服务端拒绝对该请求提供服务。
415 Unsupported Media Type
因为请求中提交的互联网媒体类型不是服务端中所支持的格式,所以请求被拒绝,例如:客户端将图像上传格式是svg,但是服务端要求图像使用上传格式是jpg。
416 Requested Range Not Satisifiable(RFC 7233)
客户端已经要求文件的一部分(Byte serving),但是服务端不能提供该部分,例如:客户端要求文件的一部分超出文件尾端。
417 Expectation Failed
在请求头字段Expect中指定的预期内容无法被服务端满足,或者这个服务端是一个代理服显的证据证明在当前路由的下一个节点上,Expect的内容无法被满足。
418 I'm a teapot(RFC 2324)
该状态码是在1998年作为IEIF的传统愚人节笑话,在RFC 2343(超文本咖啡壶控制协议)中定义的,并不需要在真实的HTTP服务器中定义。
421 Misdirected Request(RFC 7540)
无法产生响应的服务端,例如:因为连接重用。
422 Unprocessable Entity(WebDAV、RFC 4918)
请求格式正确,但是由于含有语义错误,无法响应。
423 Locked(WebDAV、RFC 4918)
当前资源被锁定。
424 Failed Dependency(WebDAV、RFC 4918)
由于之前的某个请求发生的错误,导致当前请求失败,例如:RPOPPATCH。
425 Too Early(RFC 8470)
服务端拒绝处理在Early Data中的请求,以规避可能的重放冲击。
426 Upgrade Required(RFC 2817)
客户端应该切换到Upgrade头字段中给出的不同协议,例如:TLS/1.0。
428 Precondition Required(RFC 6585)
原服务端要求该请求满足一定条件,这是为了防止未更新问题,即客户端通过读取(GET)一个资源的状态,并且更改它,并且将它写(PUT)回服务端,但是这期间第三方已经改在服务端上更改了该资源的状态,因此导致了冲突。
429 Too Many Requests(RFC 6585)
用户在给定的时间内发送了太多的请求,用于网络限速。
431 Request Header Fields Too Large(RFC 6585)
服务端不愿意处理请求,因为一个或者多个头字段过大。
451 Unavailable For Legal Reasons
该请求因为法律的要求而被拒绝,由IETF在2015年核准后新增加。
5XX服务器错误
5XX类型的状态码代表服务端无法完成明显有效的请求,服务端可能在处理请求的过程中有错误状态或者异常状态发生,也可能是服务端意识到以当前的软硬件资源无法完成对请求的处理。
500 Internal Server Error
通用错误消息,服务端遇到一个未曾预料的状况,导致了它无法完成对请求的处理,没有给出具体错误信息。
501 Not Implemented
服务端不支持当前请求所需要的某个功能,当服务端无法识别请求的方法,并且无法支持其对任何资源的请求,例如:网络服务API的新功能。
502 Bad Gateway Timeout
作为网关或者代理工作的服务端尝试执行请求时,从上游服务端接收到无效的响应。
503 Service Unavailable
由于临时的服务端维护或者过载,服务端当前无法处理请求,这个状况是暂时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个Retry-After头字段以标明这个延迟时间;如果没有给出这个Retry-After头字段,那么客户端应当以处理状态码500的方式处理它。
504 Gateway Timeout
作为网关或者代理工作的服务端尝试执行请求时,未能及时从上游服务端(URI标识出的服务端,例如:HTTP、FTP或者LDAP)或者辅助服务端(例如:DNS)收到响应。
505 HTTP Version Not Supported
服务端不支持,或者拒绝支持在请求中使用的HTTP版本,这意味着服务端不能或者不愿使用与客户端相同的版本,响应中应当包含一个描述为何版本不被支持以及服务端支持哪些协议的实体。
506 Variant Also Negotiates(RFC 2295)
它由《透明内容协商协议》(RFC 2295)扩展,代表服务端存在内部配置错误,被请求的协商变元资源被配置为透明内容协商中使用自己,因此一个协商处理中不是一个合适的重点。
507 Insufficient Storage(WebDAV、RFC 4918)
服务端无法存储完成请求所必须的内容,这个状况被认为是临时的。
508 Loop Detected(WebDAV、RFC 5842)
服务端在处理请求时陷入死循环,可以代替状态码208。
510 Not Extended(RFC 2774)
获取资源所需要的策略没有被满足。
511 Network Authentication Required(RFC 6585)
客户端需要进行身份验证才能获得网络访问权限,这是为了限制用户群访问特定网络,例如:连接WiFi热点时的强制网络门户)。
参考文献:维基百科
我的GitHub:TanJiaJunBeyond
Android通用框架:Android通用框架
我的掘金:谭嘉俊
我的简书:谭嘉俊
我的CSDN:谭嘉俊