- 计算机网络概述
- IP系列
- TCP与UDP
- 面向无连接和面向连接的服务
- UDP实时性为什么好?
- UDP数据报的组成
- TCP报文首部主要字段的含义
- TCP可靠传输的实现
- TCP发送缓存与接收缓存中的内容
- ARQ协议
- 停等ARQ协议
- 流量控制
- 拥塞控制及其算法?流量控制的协议
- 拥塞控制和流量控制的区别
- TCP三次握手的过程
- 为什么需要三次握手?
- 为什么需要第三次握手?
- 为什么要传回SYN?传递了SYN又为什还要传递ACK?
- TCP释放连接的过程
- TCP为什么是四次挥手?
- 为什么挥手时不采用三次握手?
- 为什么建立连接是三次握手,关闭连接确是四次挥手呢?
- TCP四次挥手,第四次挥手时一直丢包了怎么办?
- 为什么客户端最后还要等待2MSL?
- 如果已经建立了连接,但是客户端突然出现故障了怎么办?
- UDP和TCP的区别
- HTTP
- Session与Cookie
- 场景题
- 向淘宝请求首页,怎么提高性能
本文系记录对Java中网络的学习资料,如有异议,欢迎联系我讨论修改。PS:图侵删!图片丢失请访问:传送门
计算机网络概述
计算机网络是一个将分散的、具有独立功能的计算机系统,通过通信设备与线路连接起来,由功能完善的软件实现资源共享和信息传递的系统。简言之,计算机网络就是一些互联的、自治的、计算机系统的集合。
计算机网络的组成
- 从组成部分上看分为硬件、软件、协议
- 从工作方式上看分为边缘部分和核心部分
- 从功能组成上看分为通信子网和资源子网
计算机网络服务类型
- 面向连接/无连接
- 有应答/无应答
- 可靠/不可靠
主机间的通信方式
- 客户-服务器(C/S)
- 对等(P2P)
计算机网络体系结构
七层结构
- 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。这层的数据叫比特。
- 数据链路层:主要将从物理层接受的数据进行mac地址(网卡的地址)的封装与解封装。在这一层工作的设备为交换机,这层的数据叫帧。
- 网络层:主要将从数据链路层接受的数据进行IP地址的封装和解封装。这一层工作的设备为路由器,这层的数据叫数据报。
- 传输层:定义了一些传输数据的协议和端口号,如TCP(提供面向连接、可靠的服务),UDP(提供无连接、不可靠的服务)。主要将从网络层接受的数据进行分段传输,到达目的地后进行重组,也即负责向两台主机进程之间的通信提供通用的数据传输服务。这一层的数据叫段。
- 会话层:通过传输层(端口号:传输端口和接收端口)建立数据传输的通路。主要在系统间发起会话或接受会话的请求。
- 表示层:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等操作,也就是把计算机能识别的东西转换成人类能识别的定西。
- 应用层:主要是一些终端应用,例如FTP、Web、DNS应用。
IP层中的各种协议
IP:网际协议 IP 是 TCP/IP体系中两个最主要的协议之一,是TCP/IP体系结构网际层的核心。配套的有:
- 地址解析协议 ARP(Address Resolution Protocol)
- 网际控制报文协议 ICMP(Internet Control Message Protocol)
- 网际组管理协议 IGMP(Internet Group Management Protocol)
地址解析协议ARP:
网络层实现主机之间的通信,而链路层实现具体每段链路之间的通信。因此在通信过程中,IP 数据报的源地址和目的地址始终不变,而 MAC 地址随着链路的改变而改变。
ARP 实现由 IP 地址得到 MAC 地址。
每个主机都有一个 ARP 高速缓存,里面有本局域网上的各主机和路由器的 IP 地址到 MAC 地址的映射表。如果主机 A 知道主机 B 的 IP 地址,但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射,此时主机 A 通过广播的方式发送 ARP 请求分组,主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址,随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。
ARP攻击的第一步就是ARP欺骗。由上述“ARP协议的工作过程”我们知道,ARP协议基本没有对网络的安全性做任何思考,当时人们考虑的重点是如何保证网络通信能够正确和快速的完成——ARP协议工作的前提是默认了其所在的网络是一个善良的网络,每台主机在向网络中发送应答信号时都是使用的真实身份。不过后来,人们发现ARP应答中的IP地址和MAC地址中的信息是可以伪造的,并不一定是自己的真实IP地址和MAC地址,由此,ARP欺骗就产生了。
网际控制报文协议ICMP:
ICMP 是为了更有效地转发IP数据报和提高交付成功的机会,是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。它封装在 IP 数据报中,但是不属于高层协议。ICMP 报文分为差错报告报文和询问报文。Ping 是 ICMP 的一个重要应用,主要用来测试两台主机之间的连通性。Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文,目的主机收到之后会发送Echo回答报文。Ping会根据时间和成功响应的次数估算出数据包往返时间以及丢包率。
五层结构
应用层
应用层(application-layer)的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,如域名系统DNS,支持万维网应用的 HTTP协议,支持电子邮件的 SMTP协议等等。我们把应用层交互的数据单元称为报文。常见协议有:
- 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。 设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。
- DNS(Domain Name System,域名系统),万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。 通过域名,最终得到该域名对应的IP地址的过程叫做域名解析(或主机名解析)。DNS协议运行在UDP协议之上,使用端口号53。
- FTP 是File TransferProtocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。 基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户经常遇到两个概念:”下载”(Download)和”上传”(Upload)。 “下载”文件就是从远程主机拷贝文件至自己的计算机上;”上传”文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。在进行文件传输时,FTP 的客户端和服务器之间会建立两个 TCP 连接:21 号端口建立控制连接,20 号端口建立数据连接。
- TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。
- SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。 SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。 通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了,整个过程只要几分钟。SMTP服务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转发出的电子邮件。
域名系统DNS本质上是一个分布式数据库,为因特网的一项核心服务,用于将域名和IP地址互相映射的分布式数据库。
超文本传输协议是互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网)文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。
运输层/传输层
运输层(transport layer)的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。通用的是指并不针对某一个特定的网络应用,而是多种应用可以使用同一个运输层服务。由于一台主机可同时运行多个线程,因此运输层有复用和分用的功能。所谓复用就是指多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。运输层主要使用以下两种协议:
- 传输控制协议 TCP(Transmission Control Protocol)–提供面向连接的,可靠的数据传输服务。
- 用户数据协议 UDP(User Datagram Protocol)–提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
网络层
在 计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP/IP 体系结构中,由于网络层使用 IP 协议,因此分组也叫 IP 数据报 ,简称 数据报。
IP系列
Ping命令做了什么?基于那一个层?
Ping 是 ICMP 的一个重要应用,主要用来测试两台主机之间的连通性。Ping 的原理是通过向目的主机发送 ICMP Echo 请求报文,目的主机收到之后会发送Echo回答报文。Ping会根据时间和成功响应的次数估算出数据包往返时间以及丢包率。
网际控制报文协议——ICMP可以更有效地转发IP数据报和提高交付成功的机会,是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。它封装在 IP 数据报中,但是不属于高层协议。ICMP 报文分为差错报告报文和询问报文。
TCP与UDP
面向无连接和面向连接的服务
TCP提供面向连接的服务,在传送数据之前必须建立连接,数据传送结束后要释放连接。TCP不提供组播或广播服务。由于TCP提供的是面向连接的可靠的传输服务,因此不可避免地增加了许多开销,如确认、流量控制、计时器以及连接管理等。这不仅使得协议数据单元的头部增大很多,还要占用很多处理机资源。因此TCP主要适用于可靠性要求高的场景,例如文件传输协议FTP、超文本传输协议HTTP、远程登录TELNET等。
UDP是一个无连接的非可靠的传输层协议。它在IP之上只提供两个附加服务:分别是多路复用和对数据的错误检查。IP知道怎么把分组投递到一台主机,但是不知道怎么把它们投递给主机上的具体的应用。UDP在传送数据前不需要建立连接,远程主机的传输层接到UDP报文后也不需要给出任何确认。由于UDP协议比较简单,其执行速度快、实时性好。使用UDP的应用主要有DNS、SNMP、RTP(实时协议)
UDP实时性为什么好?
UDP没有拥塞控制,因此网络中的拥塞也不影响到主机的发送频率。而某些实时应用要求以稳定的速率发送,能容忍一些数据的丢失,但是不允许有较大的时延,而UDP刚好满足这些应用的需求。
UDP数据报的组成
UDP数据报包含两部分,分别是UDP首部和用户数据。整个UDP数据报作为IP数据报的数据部分封装在IP数据报中。UDP首部由8字节组成,分别是4个2字节的字段:
- 16位源端口号
- 16位目的端口号
- 16位UDP长度
- 16位UDP校验和
TCP报文首部主要字段的含义
- 源端口和目的端口,各占2个字节,分别写入源端口和目的端口;
- 序号字段,占4字节。TCP连接中传送的数据流中的每个字节都有一个编号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。
- 确认号(ack),占4个字节,是期望收到对方下一个报文的第一个数据字节的序号。例如,B收到了A发送过来的报文,其序列号字段是501,而数据长度是200字节,这表明B正确的收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701;
- 数据偏移(即首部长度),占4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远当该字段值为15时,TCP首部达到最大的60字节;
- 保留字段,占6位。保留今后使用,目前置零;
- 紧急位URG,让URG为1时表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应当尽快传送
- 确认ACK,仅当ACK=1时,确认号字段才有效。TCP规定,在连接建立后所有报文的传输都必须把ACK置1;
- 推送PSH,当两个应用进程进行交互式通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应,这时候就将PSH=1;
- 复位RST,当RST=1,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立连接;
- 同步SYN,在连接建立时用来同步序号。当SYN=1,ACK=0,表明是连接请求报文,若同意连接,则响应报文中应该使SYN=1,ACK=1;
- 终止FIN,用来释放连接。当FIN=1,表明此报文的发送方的数据已经发送完毕,并且要求释放;
- 校验和,占两个字节,检验和字段检验的范围包括首部和数据两部分
- 紧急指针字段,占16位,指出本报文段中有多少字节的紧急数据
- 选项字段,长度可变,TCP最初只规定了一种选项,即最大报文段长度——MSS。MSS是TCP报文段中数据字段的最大长度
- 填充字段,为了使首部长度为4字节的整数倍
TCP可靠传输的实现
- 1.应用数据被分割成 TCP 认为最适合发送的数据块。
- 2.TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
- 3.校验和:TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
- 4.TCP 的接收端会丢弃重复的数据。
- 5.流量控制:TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
- 6.拥塞控制:当网络拥塞时,减少数据的发送。
- 7.ARQ协议:也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
- 8.超时重传:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
另一版答案,着重针对发送方而言:
TCP的任务是在IP层的不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务。TCP提供的可靠数据传输服务就是要尽可能地保证接收方进程从缓存区读出的字节流与发送方发出的字节流完全一致。TCP使用了校验、序号、确认、重传等机制来达到这个目的。其中,TCP的校验机制与UDP的校验机制一致。
- 序号:TCP为每个字节进行编号,而序号字段的值表示整个报文段所发送数据的第一个字节的序号
- 确认:TCP首部的确认号是指期望对方的下一个报文段的数据的第一个字节的序号。其中TCP使用的是累计确认,即TCP只确认数据流中至第一个丢失为止的字节。例如接收方接到0-2,与6-9的报文段,由于某种原因接收方没接到3-5的报文段,此时接收方仍在等待字节3的数据,因此接收方的下一个报文段将确认号设为3
- 超时重传:TCP每发送一个报文段,便对整个报文段设置一次计时器。只要计时器设置的重传时间到期缺没收到确认,就要重传这一报文段
- 冗余ACK:TCP规定,每当比期望序号大的报文段到达时,发送一个冗余ACK,指明下一个期望字节的序号。当发送方收到对同一个报文段的3个冗余ACK时,就可以认为自己跟在这个被确认报文段之后的报文段已经丢失。
TCP发送缓存与接收缓存中的内容
发送缓存:
- 发送应用程序传给发送方TCP准备发送的数据
- TCP已经发送尚未收到确认的数据
接收缓存:
- 按序到达的但是未被接收应用程序读取的数据
- 不按序到达的数据
ARQ协议
自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ包括停止等待ARQ协议和连续ARQ协议。
停等ARQ协议
停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。
流量控制
TCP提供了流量控制服务以消除发送方使接收方缓冲区溢出的可能性,因此可以说流量控制是一个匹配速度的服务,即匹配发送方的发送速率和接收方的接收速率。TCP利用滑动窗口实现流量控制。具体实现如下:在通信中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,这就是接收窗口rwnd,即调整TCP报文段首部中的窗口字段值,从而限制发送方向网络注入报文的速率。同时,发送方根据其对当前网络拥塞程序的估计而确定的窗口值,称为拥塞窗口cwnd,其大小与网络的带宽和时延密切相关。实际上,发送方的窗口大小取值为rwnd与cwnd的最小值。若窗口字段设置为 0,则发送方不能发送数据。
拥塞控制及其算法?流量控制的协议
所谓拥塞控制就是防止过多的数据注入到网络中,这样就可以使得网络中的路由器或链路不致过载。当出现拥塞时,端点并不能了解到拥塞发生的细节,对于通信的端点来说,拥塞往往表现在通信时延的增加。为了更好地对传输层进行拥塞控制而采用了四种算法:
- 慢开始
- 拥塞避免
- 快重传
- 快恢复
慢开始算法开始运行后,每经过一个RTT(报文段往返时间)时,拥塞窗口就会加倍,以指数趋势增长,直到达到阈值S。
当采用慢开始后达到阈值S后,改用拥塞避免算法,每经过一个RTT后,拥塞窗口自增1,按照线性规律增长,当出现一次超时后,立刻将阈值S降为现在S的一般,也称乘法减,然后把拥塞窗口重置为1,开始执行慢开始算法。拥塞避免不可能完全实现网络拥塞,只是利用线性增长,降低出现拥塞的可能。
快重传和快恢复是对慢开始和拥塞避免算法的改进。快重传是当发送方连续收到3个重复的ACK报文时,直接重传对方未收到的报文段,而不必等待那个报文段设置的重传计时器超时。快恢复就是当发送方连续收到3个冗余ACK时,将阈值减半后,拥塞窗口并不直接设置为1,而是设置为阈值减半后的值,然后开始调用拥塞避免算法。
值得注意的是,发送方窗口的大小由拥塞窗口和接收窗口共同决定。
拥塞控制和流量控制的区别
拥塞控制是让网络能承受现有的网络负荷,是一个全局性的过程,涉及所有的主机、路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是指点对点的通信量控制,即接收端控制发送端,它所做的就是抑制发送端发送数据的速率,使得接收端来得及接收。
流量控制往往指在发送端和接收端之间的点对点通信量的控制。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。而拥塞控制必须确保子网能够传送待接收的数据,是一个全局性问题,涉及到网络中所有的主机、路由器以及导致网络传输能力下降的所有因素。
TCP三次握手的过程
- TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;
- TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
- TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
- TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
- 当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
为什么需要三次握手?
三次握手的目的是建立可靠的通信信道。所谓通信,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
- 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常
- 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己接收正常,对方发送正常
- 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
为什么需要第三次握手?
综述:主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
如果只有两次握手的情况:假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的。但是,两次握手的机制将会让客户端不予理睬而服务器认为连接已经建立而白白等待发送发方发送数据,这将导致不必要的错误和资源的浪费。
如果是三次握手的情况:就算是失效的报文传突然送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端已经下线而且不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接,因此无法建立连接。
为什么要传回SYN?传递了SYN又为什还要传递ACK?
SYN是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN-ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。
双方通信无误必须是两者互相发送信息都无误。传了SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要ACK信号来进行验证。
TCP释放连接的过程
- 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
- 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
- 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
- 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗ *∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
- 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
TCP为什么是四次挥手?
解释1:确保数据能够完成传输。当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
解释2:任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
为什么挥手时不采用三次握手?
如果采用三次挥手,如果发送发不等待2MSL,则发送方发出的报文中途丢失后,连接方不能进入正常关闭状态,发送方由于已经关闭,也不可能重传报文使得接收方关闭。此外,发送方在发送最后一个报文后,在2MSL时间内本次连接所产生的所有报文一定会消失,这样接收方可能再发送前一次关闭的请求。
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
TCP四次挥手,第四次挥手时一直丢包了怎么办?
第四次挥手失败,此时客户端的状态为TIME_WAIT,会等待一段时间,服务器端状态仍然为LAST_ACK,超时一段时间仍然没有响应的话,服务器端会再发起一次FIN包,告诉客户端服务器端也要断开连接的请求,客户端收到后会再次发生ACK包确认断开连接。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
为什么客户端最后还要等待2MSL?
MSL(Maximum Segment Lifetime)——最大报文寿命,TCP允许不同的实现可以设置不同的MSL值。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
UDP和TCP的区别
- 是否面向连接
- 传输是否可靠
- UDP使用数据报文段传输;TCP使用字节流传输
- UDP传输效率高,所需资源少;TCP传输效率慢,所需资源多
- UDP首部字节为8;TCP首部字节为20-60
- UDP可用于即时通信,例如QQ语音;TCP用于稳定通信,例如文件传输、邮件等
- UDP支持1对1,1对多,多对1,多对多交互通信;TCP仅支持1对1通信(不支持广播、多播)
HTTP
粘包/拆包问题的发生以及解决方案
TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。以两个数据包的发送为例,下面是可能发生的情况:
- 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包
- 服务端一次接收到了两个数据包,D1和D2粘合在一起,被称为TCP粘包
- 服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为TCP拆包
- 服务端分两次读取到了两个数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余内容D1_2和D2包的整包
发生粘包/拆包的原因:
- 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包
- 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包
- 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包
解决方案:
- 使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该长度的内容
- 设置定长消息,服务端每次读取既定长度的内容作为一条完整消息
- 设置消息边界,服务端从网络流中按消息编辑分离出消息内容
- 使用更复杂的应用层协议
HTTP请求报文的组成部分
- 请求头
- 请求行
- 请求体
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
请求头由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
- User-Agent:产生请求的浏览器类型
- Accept:客户端可识别的内容类型列表
- Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
- Connection:指定与连接相关的属性,如Connection:Keep-Alive
- Accept-Encoding:通知服务端可以发送的数据压缩格式
请求体通常不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
HTTP响应报文的组成部分
- 响应行
- 响应头
- 响应体
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>
1.响应行通过提供一个状态码来说明所请求的资源情况。状态码大致分为五类:
- 1xx:指示信息–表示请求已接收,继续处理
- 2xx:成功–表示请求已被成功接收、理解、接受
- 3xx:重定向–要完成请求必须进行更进一步的操作
- 4xx:客户端错误–请求有语法错误或请求无法实现
- 5xx:服务器端错误–服务器未能实现合法的请求
常见的状态码及其描述:
- 200 OK:客户端请求成功。
- 400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
- 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
- 403 Forbidden:服务器收到请求,但是拒绝提供服务。
- 404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
- 500 Internal Server Error:服务器发生不可预期的错误。
- 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)
2.响应头部与请求头部类似,为响应报文添加了一些附加信息,例如:
- Content-Type:响应正文的类型(是图片还是二进制字符串)
- Content-Charset:响应正文使用的编码
- Content-Language:响应正文使用的语言
HTTP的请求头和返回码
请求头:
如上上题所示
返回码:
如上题所示
HTTP状态码
1XX:通知
1XX系列响应代码仅在与HTTP服务器沟通时使用。
- 100 Continue-继续,请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
- 101 Switching Protocols-切换协议,切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
2XX: 成功
2XX系列响应代码表明操作成功了。
- 200 OK-成功,表示服务器成功执行了客户端所请求的动作
- 201 Created-已创建,请求成功并且服务器创建了新的资源
- 202 Accepted-已接受,服务器已接受请求,但尚未处理
- 203 Non-Authoritative Information-非授权信息,服务器已成功处理了请求,但返回的信息可能来自另一来源
- 204 No Content-无内容,服务器成功处理了请求,但没有返回任何内容
3XX 重定向
3XX系列响应代码表明:客户端需要做些额外工作才能得到所需要的资源。它们通常用于GET请求。他们通常告诉客户端需要向另一个URI发送GET请求,才能得到所需的表示。那个URI就包含在Location响应报头里。
- 301 Moved Permanently-永久移动:被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。对于某些使用HTTP/1.0协议的浏览器,当它们发送的POST请求得到了一个301响应的话,接下来的重定向请求将会变成GET方式。
- 302 Found-发现:临时移动,要求客户端执行临时重定向。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
- 303 See Other-查看其它地址。请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码。
- 304 Not Modified-未修改。自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容
- 305 Use Proxy-使用代理。所请求的资源必须通过代理访问
- 307 Temporary Redirect-临时重定向。在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI。与302相反,当重新发出原始请求时,不允许更改请求方法。例如,应该使用另一个POST请求来重复POST请求
- 308 Permanent Redirect-永久重定向。请求和所有将来的请求应该使用另一个URI重复。 307和308重复302和301的行为,但不允许HTTP方法更改。
301,302是http1.0的内容,303、307、308是http1.1的内容。301和302本来在规范中是不允许重定向时改变请求方法的(将POST改为GET),但是许多浏览器却允许重定向时改变请求方法(这是一种不规范的实现)。301表示搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。
永久是指原来访问的资源已经永久删除啦,客户端应该根据新的URI访问重定向。临时是指访问的资源可能暂时先用location的URI访问,但旧资源还在的,下次你再来访问的时候可能就不用重定向了。
4XX:客户端错误
这些响应代码表明客户端出现错误。不是认证信息有问题,就是表示格式或HTTP库本身有问题。客户端需要自行改正。
- 400 Bad Request 这是一个通用的客户端错误状态,当其他4XX响应代码不适用时,就采用400。此响应代码通常用于服务器不理解请求的语法
- 401 Unauthorized-未授权,请求要求身份验证。对于需要登录的网页,服务器可能返回此响应
- 403 Forbidden-禁止 服务器拒绝请求。该响应代码常用于一个资源只允许在特定时间段内访问,或者允许特定IP地址的用户访问的情况。403暗示了所请求的资源确实存在。
- 404 Not Found-未找到。404表明服务器无法把客户端请求的URI转换为一个资源即找不到资源
- 405 Method Not Allowed-方法禁用,禁用请求中指定的方法
- 407 Proxy Authentication Required-请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
- 408 Request Time-out,服务器等候请求时发生超时
- 409 Conflict-冲突,请求的操作会导致服务器的资源处于一种不可能或不一致的状态
- 410 Gone-已删除,如果请求的资源已永久删除,服务器就会返回此响应
5XX 服务端错误
这些响应代码表明服务器端出现错误。一般来说,这些代码意味着服务器处于不能执行客户端请求的状态,此时客户端应稍后重试。有时,服务器能够估计客户端应在多久之后重试。并把该信息放在Retry-After响应报头里。
- 500 Internal Server Error-内部错误,服务器遇到错误,无法完成请求。对于大多数web框架,如果在执行请求处理代码时遇到了异常,它们就发送此响应代码
- 501 Not Implemented-尚未实施,服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
- 502 Bad Gateway-错误网关,服务器作为网关或代理,从上游服务器收到无效响应
- 503 Service Unavailable-服务不可用,服务器目前无法使用(由于超载或停机维护)
- 504 Gateway Time-out-网关超时,服务器作为网关或代理,但是没有及时从上游服务器收到请求
- HTTP Version not supported-HTTP版本不受支持,服务器不支持请求中所用的 HTTP 协议版本
HTTP中Content-type类型有哪些
- HTML:text/html
- JSON:application/json
- JPG:application/x-jpg
- JSP:text/html
长连接与短连接
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:Connection:keep-alive。在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户端适合使用长连接。在长连接的应用场景下,client端一般不会主动关闭连接,当client与server之间的连接一直不关闭,随着客户端连接越来越多,server会保持过多连接。这时候server端需要采取一些策略,如关闭一些长时间没有请求发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件允许则可以限制每个客户端的最大长连接数,这样可以完全避免恶意的客户端拖垮整体后端服务。短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费较多时间和带宽。
长连接与短连接各自的应用场景
- 长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。数据库的连接用长连接。
- 短链接多用于WEB网站的http服务,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源。并发量大,但每个用户无需频繁操作情况下需用短连好。
HTTP的无状态特性
HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。
如何解决HTTP的无状态性?
使用Session和Cookie。Session机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的Session之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。
HTTP1.0和HTTP1.1的区别
- 长连接 : 在HTTP/1.0中,默认使用的是短连接,也就是说每次请求都要重新建立一次连接。HTTP是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。HTTP1.1起,默认使用长连接 ,默认开启Connection:keep-alive。HTTP/1.1的持续连接有非流水线方式和流水线方式。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。
- 错误状态响应码:在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
- 缓存处理 :在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since,If-Match,If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
- 支持分块传输编码
- 支持流水线
- 支持同时打开多个 TCP 连接
- 支持虚拟主机
HTTP2.0相比1.0和1.1的新特性
- 新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
- 多路复用(MultiPlexing),即连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
- header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
- 服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能。
服务端推送的含义
服务端推送能把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。正因为没有发起请求,建立连接等操作,所以静态资源通过服务端推送的方式可以极大地提升速度。
头部压缩存在的意义
假定一个页面有100个资源需要加载(这个数量对于今天的Web而言还是挺保守的), 而每一次请求都有1kb的消息头(这同样也并不少见,因为Cookie和引用等东西的存在),则至少需要多消耗100kb来获取这些消息头。HTTP2.0可以维护一个字典,差量更新HTTP头部,大大降低因头部传输产生的流量。
HTTP2.0中的多路复用和HTTP1.x中的长连接复用有何区别
- HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;
- HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
- HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
HTTP中Get和Post区别
标准答案:
- GET会将参数暴露在url上,某种程度上不安全,而POST将参数放在Request body中
- GET在url中传送的参数长度有限制,POST在Request body没有长度、数量限制
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
- GET只能进行url编码,而POST可以支持多种编码方式
- GET请求会被浏览器主动cache,而POST不会,除非手动设置
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
- GET在浏览器回退时是无害的,而POST会再次提交请求
加分答案: GET和POS本质上都是TCP连接,上述区别的根本原因在于,HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。例如,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。如果在GET的Request Body中偷带数据,但是不保证该数据会被处理。
此外,GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
因此,应该注意:
- GET与POST都有自己的语义,不能随便混用。 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
- 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
HTTPS和HTTP的区别
- HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源
HTTPS发起请求的流程
1.客户端发出加密通信请求ClientHello
客户端提供:
- 1.协议版本(如TSL1.0)
- 2.随机数1(用于生成对话密钥)
- 3.支持的加密方法(如RSA公钥加密)
- 4.支持的压缩方法
2.服务器回应SeverHello
采用HTTPS协议的服务器必须要有一套数字证书,可以是自己制作或者CA证书。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用CA证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。公钥给别人加密使用,私钥给自己解密使用。服务器回应内容:
- 1.确认使用的加密通信协议版本(TSL1.0)
- 2.随机数2(用于生成对话密钥)
- 3.确认加密方法(RSA)
- 4.服务器证书(包含非对称加密的公钥)
- 5.(可选)要求客户端提供证书的请求
3.客户端解析证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等。如果证书不是可信机构颁布,或证书域名与实际域名不符,或者证书已经过期,就会向访问者显示一个警告,是否继续通信。证书的解析工作由客户端自己执行。如果证书没有问题,那么就生成一个随即值,然后用证书对该随机值进行加密。
4.客户端传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。发送内容为:
- 1.随机数3(pre-master key,此随机数用服务器公钥加密,防止被窃听)
- 2.编码改变通知(表示随后的信息都将用双方商定的方法和密钥发送)
- 3.客户端握手结束通知
5.服务端解密信息
服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
6.生成会话秘钥
双方同时有了三个随机数,接着就用事先商定的加密方法,各自生成同一把“会话密钥” 服务器端用自己的私钥(非对称加密的)获取第三个随机数,会计算生成本次所用的会话密钥(对称加密的密钥)。
7.传输加密后的信息
这部分信息是服务端用私钥加密后的信息,可以在客户端被还原。
8.客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。
SSL与TSL
- SSL:(Secure Socket Layer) 安全套接层,于 1994 年由网景公司设计,并于 1995 年发布了 3.0 版本
- TLS:(Transport Layer Security)传输层安全性协议,是 IETF 在 SSL3.0 的基础上设计的协议
上述两种技术的出现是为了解决HTTP中存在的安全性问题。例如,使用明文通信,内容被窃听;不验证身份,身份可伪装;无法验证报文完整性,容易被篡改。
HTTPS=HTTP+TSL,并使用TSL作为安全保障,对传输内容加密并做身份验证。
CA
证书:全称公钥证书(Public-Key Certificate, PKC),里面保存着归属者的基本信息,以及证书过期时间、归属者的公钥,并由认证机构(Certification Authority, CA)施加数字签名,表明,某个认证机构认定该公钥的确属于此人。数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。
服务器的运营人员向CA提出公开密钥的申请,CA在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。进行HTTPS通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。
URL与URI的区别
- URI(Uniform Resource Identifier)是同一资源标志符,可以唯一标识一个资源。
- URL(Uniform Resource Location)是同一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
- URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。
Session与Cookie
Cookie
由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
####Cookie的设置和发送过程 答案1:
- 客户端发送一个http请求到服务器端
- 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部
- 客户端发送一个http请求到服务器端,其中包含Cookie头部
- 服务器端发送一个http响应到客户端
答案2:
- 用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;
- 服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体 (Response Body)中的,而是存放于HTTP响应头(Response Header)
- 客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置。
- 对于Windows操作系统而言,我们可以从: [系统盘]:\Documents and Settings[用户名]\Cookies目录中找到存储的Cookie;
- 客户端再次向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(equest Header)了。
Set-Cookie的意义
当服务器返回给客户端一个Http响应信息时,其中如果包含Set-Cookie这个头部,说明:
- 指示客户端建立一个Cookie
- 在后续的Http请求中自动发送这个Cookie到服务器端,直到这个Cookie过期。
- 如果Cookie的生存时间是整个会话期间的话,那么浏览器会将 Cookie保存在内存中, 浏览器关闭时就会自动清除这个Cookie。
- 如果将Cookie保存在客户端的硬盘中,浏览器关闭的话,该Cookie 也不会被清除,下次打开浏览器访问对应网站时,这个Cookie就会自动再次发送到服务器端。
Cookie的其他特性
- Cookie具有不可跨域名性。 根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。 Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。
- Cookie不支持中文,需要编码
Cookie的不可跨域性
答案是否定的。Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。
Session
Session是一种记录客户状态的机制,不同于Cookie的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
Session的创建与使用过程
Session在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法, 在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。当一个用户第一次访问某个网站时会自动创建HttpSession,每个用户可以访问他自己的HttpSession。 创建Session的同时,服务器会为该Session生成唯一的session id, 这个session id在随后的请求中会被用来重新获得已经创建的Session。
Session被创建之后,就可以调用Session相关的方法往Session中增加内容了, 而这些内容只会保存在服务器中,发到客户端的只有session id。可以通过HttpServletRequest对象的getSession方法获得HttpSession。 通过HttpSession的setAttribute方法可以将一个值放在HttpSession中, 通过调用HttpSession对象的getAttribute方法,同时传入属性名就可以获取保存在HttpSession中的对象。
当客户端再次发送请求的时候,会将这个session id带上,服务器接受到请求之后就会依据session id找到相应的Session,从而再次使用Session。
Session的生命周期
Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存中。每个用户都会有一个独立的Session。这个Session使用一个Session ID来标识这个Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。 如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session”活跃(active)”了一次。
例如,当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的Session。
-Session的有效期
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
Session如何传递Session id
- 保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器
- 由于cookie可以被人为的禁止,必须有其它的机制以便在cookie被禁止时仍然能够把session id传递回服务器,经常采用的一种技术叫做URL重写,就是把session id附加在URL路径的后面,附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。网络在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id
- 另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器
Cookie和Session的应用场景
- Cookie应用于记录上次访问时间;浏览记录
- Session应用于购物车
Session和Cookie的区别
- Session工作在Server中;Cookie工作在Client
- 二者均工作在内存中,也可以做持久化
- Session会对服务器产生一定的性能压力,有条件可以组集群;Cookie则不会产生高负载
- 单个Cookie在客户端的限制是4KB
- 在以亿为单位的网站中,即使是小容量的Cookie也会带来巨大的网络流量
- Session相比Cookie支持更多的数据类型
- Session的生命周期长于Cookie(关闭就没了)
如何保证Cookie的安全性?比如你的cookies被拷贝了?
- 设置Cookie的有效期不要太长
- 设置HTTPOnly属性为true
- 设置复杂的Cookie并加密:cookie的key使用uuid,随机生成;cookie的value可以使用复杂组合
- 用户第一次登录时,保存ip+cookie加密后的token
- 同时使用Session和Cookie
- 如果网站支持https,尽可能使用https
Cookie被禁用的解决办法
最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面。
场景题
在浏览器中输入url地址->显示主页的过程中发生了什么
- 1.DNS解析
- 2.TCP连接
- 3.发送HTTP请求
- 4.服务器处理请求
- 5.服务器返回HTTP报文
- 6.浏览器解析渲染页面
1.DNA解析的过程是递归的,下面以请求www.google.com为例:首先在本地域名服务器中查询IP地址,如果没有找到的情况下,本地域名服务器会向根域名服务器发送一个请求,如果根域名服务器也不存在该域名时,本地域名会向com顶级域名服务器发送一个请求,依次类推下去。直到最后本地域名服务器得到google的IP地址并把它缓存到本地,供下次查询使用。从上述过程中,可以看出网址的解析是一个从右向左的过程: com -> google.com -> www.google.com。
2.HTTP协议是使用TCP作为其传输层协议的,当TCP出现瓶颈时,HTTP也会受到影响。
3.发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口(HTTP协议80/8080, HTTPS协议443)。HTTP请求报文是由三部分组成: 请求行, 请求报头和请求体。请求行格式及示例如下:
Method Request-URL HTTP-Version CRLF
GET index.html HTTP/1.1
常用的方法有:GET, POST, PUT, DELETE, OPTIONS, HEAD
4.略
5.后端从在固定的端口接收到TCP报文开始,这一部分对应于编程语言中的socket。它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应体。
6.浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。
向淘宝请求首页,怎么提高性能
这个题,暂时按照前端、后端、网络延迟、HTTP的基本优化来实现。
后端:
- 页面静态化缓存
网络:
- CDN加速
影响一个HTTP网络请求的因素主要有两个:带宽和延迟。如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。延迟共有三类,分别如下:
- 浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。
- DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。
- 建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。
其实这是个超级综合题,涉及到架构层次。
路由器和交换机的区别
- 工作层次不同:交换机工作在OSI开放式系统互联模型的数据链路层,也就是第二层,而路由器则工作在OSI模型的网络层,就是第三层。
- 数据的转发对象不同: 交换机是根据MAC地址转发数据帧,而路由器则是根据IP地址来转发IP数据报/分组。
- 分工:交换机主要是用于组建局域网,而路由器则是负责让主机连接外网。
详细描述DNS寻址过程
- 在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
- 如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
- 如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
- 如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
- 如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。
- 如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。