OSI七层网络模型
Open System Interconnect 开放式系统互联,一般叫做OSI参考模型,是一种网络互联模型和规范。他定义了七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),每一层实现各自的功能和协议,并完成与相邻层的接口通信。各层提供的服务与这些服务怎么实现的无关。
七层模型总结
| OSI参考模型 | 层次解释 | 实例 |
|---|---|---|
| 物理层 | 设备间传输原始的比特流 | 集线器、网线、中继器 |
| 数据链路层 | 成帧、介质访问和差错检测 | 网卡、网桥、二层交换机 |
| 网络层 | IP选址和路由选择、分组转发数据 | IP、RIP、OSPF、路由器、多层交换机、防火墙 |
| 传输层 | 建立、管理和维护端到端的连接、进程间的逻辑通信 | TCP、UDP、进程、端口(socket) |
| 会话层 | 访问验证、会话管理 | 用户登录、断点续传 |
| 表示层 | 数据格式转换和数据加密 | URL加密、图片编码 |
| 应用层 | 对应用程序提供服务、访问网络的接口 | HTTP(S)、DNS、FTP |
七层模型详解
- 物理层 实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流(通过硬件设备将模拟信号转换为数字信号,于是有了0/1数据流,叫做比特流)。规定了电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。
- 数据链路层 可以发比特流但是没有格式就会乱七八糟,于是就有了”帧”(将比特组合成字节,再将字节组合成帧)。为了确保数据通信的准确,实现数据有效的差错控制,加入了检错等功能
- 网络层 本层通过IP寻址来建立两个节点之间的连接,为源端传输层发送过来的数据分组选择合适的路由和交换节点,正确的按照地址发送到目的端的传输层。前两层都是在于可以发数据,以及发的数据是否正确,然而如果连着两台电脑还行,多台电脑而又只想让其中一台可以通信,则需要路由。选择性的发,那每台电脑就得有自己的身份,于是出现了IP协议等。
- 传输层 比特流传输的过程不可能会一直顺畅,偶尔出现中断很正常,如果人为制定出单位,分成一个个的信息段,从中又衍生了报文,结合上面几层,我们就可以有目标的发生正确数据给某台计算机了,传输层有两个重要的协议:TCP和UDP。TCP效率低但是发送包会校验是否完整,UDP效率高但是不管别人能否完整收到。
- 会话层 会话层不参与具体的传输,它提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制。计算机收到了发送的数据,但是有那么多进程,具体哪个进程需要用到这个数据,则把他输送到那个进程。例如:如果80端口要用,所以系统内数据通信,将接收端口数据送至需求端口。
- 表示层 解决用户信息的语法表示问题,它将欲交换的数据从适合某一用户的抽象语法,转换为适合于OSI 系统内部使用的传送语法。现在正确接收到了需要的数据,但是因为数据在传输过程中可能基于安全性,或者是算法上的压缩,还有就是网络类型不同。那就得有一个沟通的桥梁来整理整理,还原出原本应该有的表示,类似于一个拆快递的过程。
- 应用层 最靠近用户的一层,提供多种服务,用户只需操作应用层就可以得到服务内容,这样封装可以让更多的人能使用它。包含的主要协议:FTP(文件传送协议)、Telnet(远程登录协议)、DNS(域名解析协议)、SMTP(邮件传送协议),POP3协议(邮局协议),HTTP协议(Hyper Text Transfer Protocol)
端到端与点到点通信
端到端通信
端到端通信是针对传输层来说的,它是一个网络连接,因为网络之间的通信必须要建立连接,实现应用程序之间的通信,不需要知道底层是如何传输的。实际上它是一条逻辑链路,这条逻辑链路可能经过了很复杂的物理路线。 端到端通信指的是在数据传输前,经过各种各样的交换设备,在两端设备间建立一条链路(在这两端之间不管有多少其他设备都忽略),就像它们是直接相连的一样,链路建立后,发送端就可以发送数据,直至数据发送完毕,接收端确认接收成功。
点到点通信
点到点通信是针对数据链路层或网络层来说的,点对点是基于 MAC 地址或者 IP 地址,是指一个设备发数据给另外一个设备,这些设备是指直连设备(即直接连接的设备)包括网卡,路由器,交换机。 点到点通信指的是发送端把数据传给与它直接相连的设备,这台设备在合适的时候又把数据传给与之直接相连的下一台设备,通过一台一台直接相连的设备,把数据传到接收端。
TCP协议
TCP的优点:
可靠稳定:TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。 TCP连接传送的数据,无差错,不丢失,不重复,且按序到达。
TCP的缺点:
- 慢、效率低:TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间
- 占用系统资源高:要在每台设备上维护所有的传输连接,每个连接都会占用系统的CPU、内存等硬件资源
- 易被攻击:因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
TCP是可靠协议?
很明确地说,从通信意义上推敲,TCP一点都不可靠。一个抽象的协议,怎么可能左右介质来保证可靠,不存在的。但凡是经由某种介质的通信行为均不可能是绝对可靠的!
正好比我们现实生活中的保险,其实它什么都不能阻止,什么风险也保证不了它的不发生,它保证不了飞机不会掉下来,也无法阻止人生病…事实上,TCP就是通信中的保险业。
参考两军问题我们知道网络通信中存在一致性确认问题,通信双方都要保证数据一致性。但是一致性是不可能的,谁也无法保证数据在传输过程中是否丢失。那么通信技术还有什么意义呢?
那么信道到底不可靠到什么程度?是100%不可靠吗?如果是的话,意味着断路,即双方是不可达的,无论我们发送多少次数据包,均会丢失,这样我们马上可以结束这个没有意义的讨论,因此,所谓的不可靠只是说信道会出现概率性丢包,丢包概率pp一定是介于开区间(0,1)之间的!
这个意义十分重大,这意味着,只要我们重试消息的次数足够多,就一定能收到来自对端针对消息的确认!,这是完全确定的一个结论。
事实上,通信协议从来都不是为了满足完全的一致性需求,其次,通信传输的是字节电脉冲,消息可以重发,这使得我们的TCP协议在信道传输不可靠程度上得到缓和,也就是我们买保险一样,规避损失。
TCP为何要三次握手
TCP为什么是3次握手,而不是2次,也不是4次,5次呢?所谓的TCP建立连接的握手,实质上就是建立一个双向的可靠通信连接,一边一个来回,每一边都自带超时重传来确保可靠性(而不是靠握手的次数)。TCP的3次握手是优化的结果,其实它应该是4次握手,由于是从零开始的建立连接,因此将SYN的ACK以及被动打开的SYN合并成了一个SYN-ACK,仅此而已。
这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足”在不可靠信道上可靠地传输信息”这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了. 因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了”。
TCP请求报文内容
- Seq:序号,用来标识TCP发端向TCP收端发送的数据字节流,是本报文段发送的数据组的第一个字节的序号,在TCP传送的流中,每一个字节一个序号。一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号Seq=400。序号确保了TCP传输的有序性。
- Ack:确认序号,即接收到的上一次远端主机传来的seq+1,再发送给远端主机。提示远端主机已经成功接收上一次所有数据。只有ACK标志位为1时,Ack才有效。
- ACK:确认序号有效
- SYN:同步,在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此,SYN置1就表示这是一个连接请求或连接接受报文。
- FIN:当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
TCP11种状态
- CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”。
- LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接。
- SYN_RCVD :表示服务器接收到了来自客户端请求连接的SYN报文。在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat很难看到这种状态,除非故意写一个监测程序,将三次TCP握手过程中最后一个ACK报文不予发送。当TCP连接处于此状态时,再收到客户端的ACK报文,它就会进入到ESTABLISHED 状态。
- SYN_SENT :这个状态与SYN_RCVD 状态相呼应,当客户端SOCKET执行connect()进行连接时,它首先发送SYN报文,然后随即进入到SYN_SENT 状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT 状态表示客户端已发送SYN报文。
- ESTABLISHED :表示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()主动要求关闭连接。注意:FIN_WAIT_2 是没有超时的(不像TIME_WAIT 状态),这种状态下如果对方不关闭(不配合完成4次挥手过程),那这个 FIN_WAIT_2 状态将一直保持到系统重启,越来越多的FIN_WAIT_2 状态会导致内核crash。
- TIME_WAIT :表示收到了对方的FIN报文,并发送出了ACK报文。 TIME_WAIT状态下的TCP连接会等待2*MSL(Max Segment Lifetime,最大分段生存期,指一个TCP报文在Internet上的最长生存时间。每个具体的TCP协议实现都必须选择一个确定的MSL值,RFC 1122建议是2分钟,但BSD传统实现采用了30秒,Linux可以cat /proc/sys/net/ipv4/tcp_fin_timeout看到本机的这个值),然后即可回到CLOSED 可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(这种情况应该就是四次挥手变成三次挥手的那种情况)
- CLOSING :这种状态在实际情况中应该很少见,属于一种比较罕见的例外状态。正常情况下,当一方发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING 状态表示一方发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?那就是当双方几乎在同时close()一个SOCKET的话,就出现了双方同时发送FIN报文的情况,这是就会出现CLOSING 状态,表示双方都正在关闭SOCKET连接。
- CLOSE_WAIT :表示正在等待关闭。怎么理解呢?当对方close()一个SOCKET后发送FIN报文给自己,你的系统毫无疑问地将会回应一个ACK报文给对方,此时TCP连接则进入到CLOSE_WAIT状态。接下来呢,你需要检查自己是否还有数据要发送给对方,如果没有的话,那你也就可以close()这个SOCKET并发送FIN报文给对方,即关闭自己到对方这个方向的连接。有数据的话则看程序的策略,继续发送或丢弃。简单地说,当你处于CLOSE_WAIT 状态下,需要完成的事情是等待你去关闭连接。
- LAST_ACK :当被动关闭的一方在发送FIN报文后,等待对方的ACK报文的时候,就处于LAST_ACK 状态。当收到对方的ACK报文后,也就可以进入到CLOSED 可用状态了。
TCP三次握手的目的
三次握手的目的是同步连接双方的序列号和确认号并交换 TCP 窗口大小信息。旨在确定两个双向的初始序列号,TCP用序列号来编址传输的字节,由于是两个方向的连接,所以需要两个序列号,握手过程不传输任何字节,仅仅确定初始序列号
TCP三次握手原理
假设客户端为A,服务端为B。
| 握手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第一次 | A:SYN_SENT | SYN=1,ACK=0,Ack=无效,Seq=2019 | B:空闲 |
在第一次握手过程中,发起连接请求报文,使得SYN=1,ACK=0,因为ACK=0,导致Ack无效。假设客户端A向服务端B发送请求,报文序号Seq=2019。
发送完毕后,客户端进入SYN_SENT状态,等待服务端接受(服务端此时不知道A发来消息,处于空闲状态)
| 握手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第二次 | B:空闲->SYN_RCVD | SYN=1,ACK=1,Ack=2020,Seq=2333 | A:SYN_SENT |
在第二次握手过程中,服务端接受客户端请求,使得SYN=1,ACK=1,激活Ack,Ack=2019+1=2020。假设服务端B向服务端B发送确认请求,报文序号Seq=2333。
发送完毕后,服务端马上从空闲状态进入SYN_RCVD状态。
| 握手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第三次 | A:TABLISHED | SYN=0,ACK=1,Ack=2334,Seq=2021 | B:SYN_RCVD->TABLISHED |
在第三次握手过程中,客户端接收到来自服务端的确认后,进行数据检测,判断Ack==Seq(第一次客户端自己的序号)+1,ACK==1。满足条件,置得ACK=1,Ack=Seq(第二次握手服务端发送过来的序号)+1,注意此时不再使用SYN了,因为SYN做同步用,能够第三次握手表明前面双方序号确认没问题。
发送完毕后,客户端进入TABLISHED(连接)状态,等待服务端接受,服务端接受后,判断Ack==Seq(第二次握手服务端自己的序号)+1,ACK==1,满足条件,服务端进入TABLISHED状态,连接建立完毕。

TCP四次挥手原理
实际上客户端和服务端任何一方都可以来进行CLOSE操作,因为TCP是全双工通信的。仍然指定A为客户端,B为服务端,且设定由客户端执行CLOSE操作请求。
| 挥手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第一次 | A:TABLISHED->FIN_WAIT_1 | SYN=1,ACK=0,Ack=无效,FIN=1,Seq=4096 | B:TABLISHED |
在第一次挥手过程中,客户端发起关闭请求报文,此时不需要同步和确认,所以置SYN=0,ACK=0,Ack=无效,发送FIN=1,假设客户端A向服务端B发送关闭请求,报文序号Seq=4096。
发送完毕后,客户端由TABLISHED连接状态进入FIN_WAIT_1(关闭等待1)状态,等待服务端接受(服务端此时不知道A发来消息,仍然处于连接状态)
| 挥手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第二次 | B:TABLISHED->CLOSE_WAIT | SYN=0,ACK=1,Ack=4097,Seq=2333 | A:FIN_WAIT_1->FIN_WAIT_2 |
在第二次挥手过程中,服务端接受客户端请求,不需要请求同步使得SYN=0,该次回应需要确定序号使得ACK=1,激活Ack=4096+1=4097。假设服务端B向客户端A发送确认请求,报文序号Seq=2333。
发送完毕后,服务端马上从连接状态进入CLOSE_WAIT(等待确认关闭)状态。
| 挥手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第三次 | B:CLOSE_WAIT->LAST_ACK | SYN=0,ACK=1,Ack=4097,Seq=9999 | A:FIN_WAIT_2 |
在第三次挥手过程中,服务端发送FIN=1,确认服务端可以关闭了,置ACK=1,激活Ack=4096+1=4097,假设服务端B向客户端A发送确认请求,报文序号Seq=9999。
| 挥手 | 源端:状态 | 数据报文 | 目的端:状态 |
|---|---|---|---|
| 第四次 | A:FIN_WAIT_2->TIME_WAIT | SYN=0,ACK=1,Ack=10000,Seq=4097 | B:CLOSED |
客户端接收到FIN后,进入TIME_WAIT状态,接着向服务端发送一个请求,服务端彻底关闭连接
发送完毕后,连接关闭完成。

TCP面试问题
1. 为什么要TIME_WAIT等待呢?
为了防止这种情况:A接到B的释放连接请求后会发送一个确认信息,但是如果这个确认信息丢了,也就是B没有收到确认释放连接,那么B就会重发一个释放连接请求,这时候A还处于TIME_WAIT状态,所以会再次发送一个确认信息。
2. 为什么TIME_WAIT 状态还需要等2MSL秒之后才能返回到CLOSED 状态呢?
因为虽然双方都同意关闭连接了,而且握手的4个报文也都发送完毕,按理可以直接回到CLOSED 状态(就好比从SYN_SENT 状态到ESTABLISH 状态那样),但是我们必须假想网络是不可靠的,你无法保证你最后发送的ACK报文一定会被对方收到,就是说对方处于LAST_ACK 状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT 状态的作用就是用来重发可能丢失的ACK报文。
3. 为什么不能用两次握手进行连接
3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
4. 如果已经建立了连接,但是客户端突然出现故障了怎么办
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
UDP协议
UDP的优点
- 快:UDP是一个无状态的传输协议,所以它在传递数据时非常快
- 比TCP稍安全:UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些
UDP的缺点
- 不可靠,不稳定:因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。
TCP协议对比UDP协议
| 类别 | 优点 | 缺点 | 连接与状态 | 方式 | 使用场景 | 通信 | 连接方式 |
|---|---|---|---|---|---|---|---|
| TCP | 可靠稳定 | 慢、不安全、占资源 | 面向连接、有状态 | 面向字节流 | 对网络通讯质量有要求,传输大量数据 | 全双工可靠信道 | 点到点 |
| UDP | 快、稍安全 | 不可靠、不稳定、易丢包、不保证数据顺序 | 面向无连接、无状态 | 面向报文 | 网络负担重、响应速率要求高、可靠性要求不高 | 全双工不可靠信道 | N:N交互通信 |
TCP相比UDP为什么是可靠的
- 确认和重传机制:建立连接时三次握手同步双方的“序列号 + 确认号 + 窗口大小信息”,是确认重传、流控的基础传输过程中,如果Checksum校验失败、丢包或延时,发送端重传
- 数据排序:TCP有专门的序列号SN字段,可提供数据re-order重排序
- 流量控制:窗口和计时器的使用。TCP窗口中会指明双方能够发送接收的最大数据量
- 拥塞控制:TCP的拥塞控制由4个核心算法组成。
- “慢启动”(Slow Start)
- “拥塞避免”(Congestion avoidance)
- “快速重传 ”(Fast Retransmit)
- “快速恢复”(Fast Recovery)
DNS协议
域名是分层结构,域名服务器也是对应的层级结构
有了域名结构,还需要有一个东西去解析域名,域名需要由遍及全世界的域名服务器去解析,域名服务器实际上就是装有域名系统的主机。
| 协议名 | 端口 | OSI层级 | 格式 | 作用 | 结构 |
|---|---|---|---|---|---|
| DNS | 53 | 应用层 | UDP | 域名解析服务 | 树形层次结构 |
由高向低进行层次划分,可分为以下几大类:
| 分类 | 作用 |
|---|---|
| 根域名服务器 | 最高层次的域名服务器,本地域名服务器解析不了的域名就会向其求助 |
| 顶级域名服务器 | 负责管理在该顶级域名服务器下注册的二级域名 |
| 权限域名服务器 | 负责一个区的域名解析工作 |
| 本地域名服务器 | 当一个主机发出DNS查询请求时,这个查询请求首先发给本地域名服务器 |
- 每个层的域名上都有自己的域名服务器,最顶层的是根域名服务器
- 每一级域名服务器都知道下级域名服务器的IP地址
- 为了容灾, 每一级至少设置两个或以上的域名服务器
DNS查询方法
- 递归查询:本机向本地域名服务器发出一次查询请求,就静待最终的结果。如果本地域名服务器无法解析,自己会以DNS客户机的身份向其它域名服务器查询,直到得到最终的IP地址告诉本机
- 迭代查询:本地域名服务器向根域名服务器查询,根域名服务器告诉它下一步到哪里去查询,然后它再去查,每次它都是以客户机的身份去各个服务器查询。
通俗地说,递归就是把一件事情交给别人,如果事情没有办完,哪怕已经办了很多,都不要把结果告诉我,我要的是你的最终结果,而不是中间结果;如果你没办完,请你找别人办完。 迭代则是我交给你一件事,你能办多少就告诉我你办了多少,然后剩下的事情就由我来办。
解析过程
域名解析总体可分为一下过程: (1) 输入域名后, 先查找自己主机对应的域名服务器,域名服务器先查找自己的数据库中的数据. (2) 如果没有, 就向上级域名服务器进行查找, 依次类推 (3) 最多回溯到根域名服务器, 肯定能找到这个域名的IP地址 (4) 域名服务器自身也会进行一些缓存, 把曾经访问过的域名和对应的IP地址缓存起来, 可以加速查找过程 具体可描述如下:
- 主机先向本地域名服务器进行递归查询
- 本地域名服务器采用迭代查询,向一个根域名服务器进行查询
- 根域名服务器告诉本地域名服务器,下一次应该查询的顶级域名服务器的IP地址
- 本地域名服务器向顶级域名服务器进行查询
- 顶级域名服务器告诉本地域名服务器,下一步查询权限服务器的IP地址
- 本地域名服务器向权限服务器进行查询
- 权限服务器告诉本地域名服务器所查询的主机的IP地址
- 本地域名服务器最后把查询结果告诉主机
HTTP协议
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,基于TCP/IP通信协议来传递数据。是一个属于应用层的面向对象的协议
主要特点
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP请求方法
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。 HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
| 序号 | 方法 | 描述 |
|---|---|---|
| 1 | GET | 请求指定的页面信息,并返回实体主体。 |
| 2 | HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
| 3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
| 4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
| 5 | DELETE | 请求服务器删除指定的页面。 |
| 6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
| 7 | OPTIONS | 允许客户端查看服务器的性能。 |
| 8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
HTTP 响应头信息
HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。
| 应答头 | 说明 |
|---|---|
| Allow | 服务器支持哪些请求方法(如GET、POST等)。 |
| Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。 |
| Content-Length | 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。 |
| Content-Type | 表示后面的文档属于什么MIME类型。通常需要显式地指定为text/html。 |
| Date | 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。 |
| Expires | 应该在什么时候认为文档已经过期,从而不再缓存它? |
| Last-Modified | 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。 |
| Location | 表示客户应当到哪里去提取文档。 |
| Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader(“Refresh”, “5; URL=””)让浏览器读取指定的页面。 注意Refresh的意义是”N秒之后刷新本页面或访问指定页面”,而不是”每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,发送204状态代码则可以阻止浏览器继续刷新。 注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。 |
| Server | 服务器名字。 |
| Set-Cookie | 设置和页面关联的Cookie。 |
| WWW-Authenticate | 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=”executives”)。 |
HTTP状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。
HTTP状态码的英文为HTTP Status Code。
| 分类 | 分类描述 |
|---|---|
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
| 状态码 | 状态码英文名称 | 中文描述 |
|---|---|---|
| 100 | Continue | 继续。客户端应继续其请求 |
| 101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
| 200 | OK | 请求成功。一般用于GET与POST请求 |
| 201 | Created | 已创建。成功请求并创建了新的资源 |
| 202 | Accepted | 已接受。已经接受请求,但未处理完成 |
| 203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
| 204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
| 205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
| 206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
| 300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
| 301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
| 302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
| 303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
| 304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
| 305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
| 306 | Unused | 已经被废弃的HTTP状态码 |
| 307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
| 400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
| 401 | Unauthorized | 请求要求用户的身份认证 |
| 402 | Payment Required | 保留,将来使用 |
| 403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
| 404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面 |
| 405 | Method Not Allowed | 客户端请求中的方法被禁止 |
| 406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
| 407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
| 408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
| 409 | Conflict | 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突 |
| 410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
| 411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
| 412 | Precondition Failed | 客户端请求信息的先决条件错误 |
| 413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
| 414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
| 415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
| 416 | Requested range not satisfiable | 客户端请求的范围无效 |
| 417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
| 500 | Internal Server Error | 服务器内部错误,无法完成请求 |
| 501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
| 502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
| 503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
| 504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
| 505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |