计算机网络常见面试题整理

编程知识 更新时间:2023-04-28 13:34:33

体系结构

 

OSI分层(7层):物理层;数据链路层;网络层;传输层;会话层;表示层;应用层;

TCP/IP分层(4层):网络接口层;网际层;运输层;应用层;

五层协议:物理层;数据链路层;网络层;运输层;应用层;

-应用层的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程(进程:主机中正在与运行的程序)间的通信和交互的规则。对于不同的网络应用需要不同的应用层协议。在互联网中应用层协议很多,比如域名系统DNS,支持万维网应用的HTTP协议,支持电子邮件的SMTP协议等。我们把应用层交互的数据单元称为报文

-运输层的主要任务就是负责向两个主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。“通用的”是指并不针对某一特定的网络应用,而是多种应用可以使用同一运输层服务。由于一台主机可同时运行多个线程,因此运输层有复用和分用的功能。所谓复用就是指多个应用层进程可同时使用下面运输层的服务,分用和复用相反,是运输层把收到的信息分别交付上面应用层中的相应进程。运输层主要使用以下两种协议:传输控制协议TCP-提供面向连接的、可靠的数据传输服务;用户数据协议UDP-提供无连接的、尽最大努力的数据传输服务(不保证数据传输的可靠性)。运输层交互的数据单位称为报文段/用户数据报

-网络层负责为分组交换网上的不同主机提供通信服务。在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在TCP/IP体系结构中,用于网络层使用IP协议,因此分组也叫IP数据报,简称数据报。网络层的另一个任务就是选择合适的路由,使源主机传输层所传下来的分组,能通过网络层中的路由器找到目的主机。互联网是由大量的异构网络通过路由器相互连接起来的。互联网使用的网络层协议是无连接的网际协议和许多路由器选择协议,因此互联网的网络层也叫网际层或IP层。网络层交互的数据单位称为IP数据报。IP、ICMP、OSPF、IPX、RIP、IGRP(路由器)

-数据链路层通常简称为链路层,两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层的协议。在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(比如同步信息,地址信息,差错控制等)。在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始到哪个比特结束。这样,数据链路层在收到一个帧后,就可从中提出数据部分,上交网络层。控制信息还使接收端能够检测到所收到的帧中有误差错,如果发现误差,数据链路层就简单地丢弃这个出了差错的帧,以避免继续在网络中传送下去拜拜浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,还要纠错),那么就要采用可靠性传输协议来纠正出现的差错,这种方法会使链路层的协议复杂些。PPP、FR、HDLC、VLAN、MAC(网桥、交换机)、ARP、RARP

-物理层上所传送的数据单位是比特。物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化,对传送的比特流来讲,这个电路好像是看不见的。RJ45、CLOCK、IEEE802.3(中继器、集线器)

MAC地址作用 IP地址作用

MAC地址是一个硬件地址,用来定义网络设备的位置,主要由数据链路层负责。IP地址是IP协议提供的一种统一的地址格式,为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

ping的原理

ping是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。ping使用的是ICMP协议(网际层协议),它发送icmp回送请求消息给目的主机,icmp协议规定,目的主机必须返回icmp回送应答消息给源主机,如果源主机在一定时间内收到应答,则认为主机可达。

假定主机A的IP地址是192.168.1.1,主机B的IP地址是192.168.1.2,都在同一子网内,则当你在主机A上运行“Ping 192.168.1.2”后,都发生了些什么呢?

首先,Ping命令会构建一个固定格式的ICMP请求数据包,然后由ICMP协议将这个数据包连同地址“192.168.1.2”一起交给IP层协议(和ICMP一样,实际上是一组后台运行的进程),IP层协议将以地址“192.168.1.2”作为目的地址,本机IP地址作为源地址,加上一些其他的控制信息,构建一个IP数据包,并在一个映射表中查找出IP地址192.168.1.2所对应的物理地址,一并交给数据链路层。其中, 映射表由ARP实现。ARP(Address Resolution Protocol)是地址解析协议,是一种将IP地址转化成物理地址的协议。后者构建一个数据帧,目的地址是IP层传过来的物理地址,源地址则是本机的物理地址,还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。

主机B收到这个数据帧后,先检查它的目的地址,并和本机的物理地址对比,如符合,则接收;否则丢弃。接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层协议。同样,IP层检查后,将有用的信息提取后交给ICMP协议,后者处理后,马上构建一个ICMP应答包,发送给主机A,其过程和主机A发送ICMP请求包到主机B一模一样。

因为ping命令是使用ICMP协议,所以没有端口号,但是有两个域:类型和代码。

DNS协议(域名与IP地址相互转换)

DNS协议是用来将域名转换为IP地址的协议(也可以将IP地址转换为相应的域名地址)

为什么不使用域名来直接进行通信呢?

  • 因为IP地址是固定长度的,IPV4是32位,IPV6是128位,而域名是变长的,不便于计算机处理
  • IP地址对于用户来说记忆不方便,但域名便于用户使用,例如www.baidu就是百度的域名。

总结来说,IP地址对面向主机的,而域名是面向用户的。

hosts文件:

域名和IP的对应关系保存在一个叫hosts文件中。最初,通过互联网信息中心来管理这个文件,如果有一个新的计算机想接入网络,或者某个计算IP变更都需要到信息中心申请变更hosts文件,其他计算姐也需要定期更新,才能上网,但是这样太麻烦了,就出现了DNS系统。

DNS系统:

1.一个组织的系统管理机构,维护系统内的每个主机的IP和主机名的对应关系

2.如果新计算机接入网络,将这个信息注册到数据库中

3.用户输入域名的时候,会自动查询DNS服务器,由DNS服务器检索数据库,得到对应的IP地址

我们可以通过命令查看自己的hosts文件:

 

在域名解析的过程中仍然会优先查找hosts文件的内容。

DNS迭代查询 递归查询

1.主机向本地域名服务器的查询一般都是采用递归查询

所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。

因此,递归查询返回的查询结果要么是所要查询的IP地址,要么是报错,表示无法查询到所需的IP地址。

2.本地域名服务器向根域名服务器的查询一般为迭代查询(DNS服务器之间的交互查询)

迭代查询的特点:当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器:“你下一步应当向哪一个域名服务器进行查询”。然后让本地服务器进行后续的查询。根域名服务器通常是把自己知道的顶级域名服务器的IP地址告诉本地域名服务器,让本地服务器再向顶级域名服务器查询。顶级域名服务器在收到本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个权限域名服务器进行查询。

最后,知道了所要解析的IP地址或报错,把这个结果返回给发起查询的主机。

递归:客户端只发一次请求,要求对方给出最终结果。

迭代:客户端发出一次请求,对方如果没有授权回答,它就会返回一个能解答这个查询的其它名称服务器列表,客户端会再向返回的列表中发出请求,直到找到最终负责所查域名的名称服务器,从它得到最终结果。

授权回答:向dns服务器查询一个域名,刚好这个域名是本服务器负责,返回的结果就是授权回答。

从递归和迭代查询可以看出:

客户端-本地dns服务端:这部分属于递归查询。(定义)

本地dns服务端---外网:这部分属于迭代查询。

递归查询时,返回的结果只有两种:查询成功或查询失败.

迭代查询,又称作重指引,返回的是最佳的查询点或者主机地址.

DNS举例解析步骤

假定域名为m.xyz的主机想知道另一个主机y.abc的IP地址。例如,主机m.xyz打算发送邮件给y.abc。这时就必须知道主机y.abc的IP地址。下面是上图a的几个查询步骤:

1、主机m.abc先向本地服务器dns.xyz进行递归查询。

2、本地服务器采用迭代查询。它先向一个根域名服务器查询。

3、根域名服务器告诉本地服务器,下一次应查询的顶级域名服务器dns的IP地址。

4、本地域名服务器向顶级域名服务器dns进行查询。

5、顶级域名服务器dns告诉本地域名服务器,下一步应查询的权限服务器dns.abc的IP地址。

6、本地域名服务器向权限域名服务器dns.abc进行查询。

7、权限域名服务器dns.abc告诉本地域名服务器,所查询的主机的IP地址。

8、本地域名服务器最后把查询结果告诉m.xyz。

整个查询过程共用到了8个UDP报文。

为了提高DNS查询效率,并减轻服务器的负荷和减少因特网上的DNS查询报文数量,在域名服务器中广泛使用了高速缓存,用来存放最近查询过的域名以及从何处获得域名映射信息的记录。

DNS域名解析

当一个用户在地址栏输入www.taobao时,DNS解析大概有10个过程:

1.浏览器先检查自身缓存中有没有被解析过的这个域名对应的IP地址,如果有,解析结束。同时域名被缓存的时间也可通过TTL属性来设置。

2.如果浏览器缓存中没有(即没命中),浏览器会检查操作系统缓存中有没有对应的已解析过的结果,而操作系统也有一个域名解析的过程,在windows中可通过c盘里一个叫hosts的文件来设置,如果你这里指定了一个域名对应的IP地址,那么浏览器会首先使用这个IP地址。

但是这种操作系统级别的域名解析规程也被很多黑客利用,通过修改你的hosts文件里的内容把特定的域名解析到他指定的IP地址上,造成所谓的域名劫持,所以在windows中将hosts文件设置成了readonly,防止被恶意篡改。

3.如果至此还没有命中域名,才会真正地请求本地域名服务器(LDNS)来解析这个域名,这台服务器一般在你的城市的某个角落,距离你不会很远,并且这台服务器的性能都很好,一般都会缓存域名解析结果,大约80%的域名解析到这里就完成了。

4.如果LDNS仍然没有命中,就直接跳到Root Server域名服务器请求解析

5.根域名服务器会返回给LDNS一个所查询域的主域名服务器(gTLD Server,国际顶尖域名服务器,如 等)地址

6.此时LDNS会再发送请求给上一步返回的gTLD

7.接受请求的gTLD查找并返回这个域名所对应的Name Server的地址,这个Name Server就是网站注册的域名服务器

8.Name Server根据映射关系表找到目标IP,返回给LDNS

9.LDNS缓存这个域名和对应的IP

10.LDNS把解析的结果返回给用户,用户根据TTL值缓存到本地系统缓存中,至此域名解析过程结束。

DNS使用的是TCP协议还是UDP协议?

DNS占用53号端口,同时使用TCP和UDP协议。那么DNS在什么情况下使用这两种协议?

DNS在区域传输的时候使用TCP协议,其他时候使用UDP协议。

DNS区域传输的时候使用TCP协议:

1.辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。

2.TCP是一种可靠连接,保证了数据的准确性。

域名解析时使用UDP协议:

客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。

ARP协议(将IP地址转换为MAC地址)数据链路层

地址解析协议。是一种将IP地址转化成物理地址的协议。

一台网络设备要发送数据给另外一台网络设备时,必须要知道对方的IP地址。但是,仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过数据链路层进行发送,而数据帧必须要包含目的MAC地址,因此发送端还必须获取到目的MAC地址。每一个网络设备在数据封装前都需要获取下一跳的MAC地址。IP地址由网络层来提供,MAC地址通过ARP协议来获取。ARP协议是TCP/IP协议簇中的重要组成部分,ARP能够通过目的IP地址发现目标设备的MAC地址,从而实现数据链路层的可达性。

ARP 工作的基本流程

ARP 工作流程分为两个阶段,一个是 ARP 请求过程,另一个是 ARP 响应过程。

工作流程如下所示:

在上面图片中,主机 A 的 IP 地址为 192.168.1.1,主机 B 的 IP 地址为 192.168.1.2。

主机 A 与主机 B 进行通信,需要获取其 MAC 地址,基本流程如下:

  • 主机 A 以广播形式向网络中所有主机发送 ARP 请求,请求包中包含了目标 IP 地址 192.168.1.2。
  • 主机 B 接收到请求,发现自己就是主机 A 要找的主机,返回响应,响应包中包含自己的 MAC 地址。

TCP三次握手和四次挥手

TCP 的三次握手

过程:

假设 A 为客户端,B 为服务器端。

首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。

  • A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x。A进入SYN_SENT状态。
  • B 收到连接请求报文,如果同意建立连接,则向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。B进入SYN_RECV状态。
  • A 收到 B 的连接确认报文后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。此时A进入ESTABLISHED状态。

B 收到 A 的确认后,连接建立。B进入ESTABLISHED状态。

总结如下

  • SYN = 1, seq = x
  • SYN = 1, ACK = 1, seq = y, ack = x+1
  • ACK = 1, seq = x+1, ack = y+1

为什么三次?(为什么不能两次?)

1、假设A发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个早已失效的报文段。但B收到此失效的连接请求报文段后,就误认为是A再次发出的一个新的连接请求。于是就向A发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要B发出确认,新的连接就建立了。由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立,并一直等待A发来数据。这样,B的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,A不会向B的确认连接报文发出确认。B由于收不到确认,就知道A并没有要求建立连接。”

2、保证能够确认双方都能明确自己和对方的收、发能力是正常的。详细解释:

第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。从客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。

第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。

而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。

经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。

而从上面的过程可以看到,至少是需要三次握手过程的。两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。

针对TCP3次握手怎么攻击?

SYN-洪水攻击

1.假设一个用户向服务器发送了SYN请求连接报文,服务端在收到请求后,会发出SYN+ACK应答报文给客户端,使连接进入半开状态,因为服务器端不确定自己发送的SYN+ACK或客户端后续反馈的ACK消息是否会丢失在半路,所以会给每个待完成的半开连接都设一个Timer,如果超过时间还没有收到客户端的ACK消息,则会重新发送一个SYN+ACK,直到重试超过一定次数时才会放弃(这段时间称为SYN Timeout),一般来说这个时间是分钟的数量级(大约为30秒-2分钟)。一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题。

2..但如果有一个恶意的攻击者大量模拟这种情况,服务器端为了维护一个非常大的半连接列表而消耗非常多的资源-数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试

3.实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃--即使服务器端的系统足够强大,服务器也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比例非常之小)。此时从正常客户的角度看来,服务器失去响应,这种情况我们称作--服务器端受到了SYN Flood攻击。

怎么防范SYN攻击?

1.最常用的一个手段就是优化主机系统设置,比如降低SYN Timeout时间,使得主机尽快释放半连接的占用;

2.采用SYN Cookie设置,比如短时间内收到某个IP的重复SYN请求,我们就认为受到了攻击。合理的采用防火墙设置等外部网络也可以进行拦截。

DDOS和DOS攻击

DDOS是DOS攻击的一种方法,但事实上DOS的攻击方式有很多种。

DOS:是Denied of Service的简称,即拒绝服务,其目的是使计算机或网络无法提供正常的服务。最常见的DOS攻击有计算机网络带宽攻击和连通性攻击。

DDOS:分布式拒绝服务攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDOS攻击,从而成倍地提高拒绝服务攻击的威力。

事实上DOS的攻击方式有很多种,比如下面的常见的:

1. SYN FLOOD

利用服务器的连接缓冲区(Backlog Queue),利用特殊的程序,设置TCP的Header,向服务器端不断地成倍发送只有SYN标志的TCP连接请求。当服务器接收的时候,都认为是没有建立起来的连接请求,于是为这些请求建立会话,排到缓冲区队列中。

如果SYN请求超过了服务器能容纳的限度,缓冲区队列满,那么服务器就不再接收新的请求了。其他合法用户的连接都被拒绝掉。可以持续SYN请求发送,直到缓冲区中都是自己的只有SYN标记的请求。

2. IP欺骗DoS攻击

这种攻击利用RST位来实现。假设现在有一个合法用户(1.1.1.1)已经同服务器建立了正常的连接,攻击者构造攻击的TCP数据,伪装自己的IP为1.1.1.1,并向服务器发送一个带有RST位的TCP数据段。服务器接收到这样的数据后,认为从1.1.1.1发送的连接有错误,就会清空缓冲区中建立好的连接。这时,如果合法用户1.1.1.1再发送合法数据,服务器就已经没有这样的连接了,该用户就必须重新开始建立连接。

攻击时,伪造大量的IP地址,向目标发送RST数据,使服务器不对合法用户服务。

3. 带宽DOS攻击

如果连接带宽足够大而服务器又不是很大,可以发送请求,来消耗服务器的缓冲区消耗服务器的带宽。这种攻击就是人多力量大了,配合上SYN一起实施DOS,威力巨大。不过是初级DOS攻击。

4. 自身消耗的DOS攻击

这是一种老式的攻击手法。说老式,是因为老式的系统有这样的自身BUG。比如Win95 (winsock v1), Cisco IOS v.10.x, 和其他过时的系统。

这种DOS攻击就是把请求客户端IP和端口弄成主机的IP端口相同,发送给主机。使得主机给自己发送TCP请求和连接。这种主机的漏洞会很快把资源消耗光。直接导致当机。这种伪装对一些身份认证系统还是威胁巨大的。

上面这些实施DOS攻击的手段最主要的就是构造需要的TCP数据,充分利用TCP协议。这些攻击方法都是建立在TCP基础上的。还有其他的DOS攻击手段。

5. 塞满服务器的硬盘

通常,如果服务器可以没有限制地执行写操作,那么都能成为塞满硬盘造成DOS攻击的途径,比如:

发送垃圾邮件。一般公司的服务器可能把邮件服务器和WEB服务器都放在一起。破坏者可以发送大量的垃圾邮件,这些邮件可能都塞在一个邮件队列中或者就是坏邮件队列中,直到邮箱被撑破或者把硬盘塞满。

让日志记录满。入侵者可以构造大量的错误信息发送出来,服务器记录这些错误,可能就造成日志文件非常庞大,甚至会塞满硬盘。同时会让管理员痛苦地面对大量的日志,甚至就不能发现入侵者真正的入侵途径。

TCP 的四次挥手(为什么四次?)

过程:

  • 客户端发送一个 FIN 段,并包含一个希望接收者看到的自己当前的序列号u。客户端进入FIN_WAIT1状态。
  • 当服务器端收到FIN包,知道了客户端想要断开连接,它会发送一个ACK包对它进行确认,确认号为u+1,序列号为v。此时服务器进入CLOSE_WAIT状态。
  • 当客户端收到了服务器端发送的ACK确认包,它知道服务器已经了解了自己想要断开连接。此时客户端进入FIN_WAIT2状态。
  • 当服务器端的数据都发送结束了,它将断开服务器端到客户端的连接,它向客户端发送一个FIN包,序列号为w,确认号依旧为u+1,此时服务器端进入LAST_ACK阶段。
  • 当客户端收到了服务器端的FIN包,它知道了服务器端也要断开连接,它向服务器发送一个ACK确认包,序列号为u+1,确认号为w+1,然后进入TIME_WAIT阶段等待2倍MSL(报文在网络中最大生存时间。一般是1-4分钟,现在对于Linux是30秒),在这个期间如果没有继续收到服务器端的FIN包,就进入了CLOSED阶段。
  • 服务器端收到客户端的ACK确认包,进入CLOSED阶段。

总结如下:

  • FIN = 1, seq = u
  • ACK = 1, ack = u+1, seq = v
  • FIN = 1, ACK = 1, ack = u+1, seq = w
  • ACK = 1, seq = u+1, ack = w+1

TIME_WAIT:

客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由

  • 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
  • 假设tcp连接是:A(1.2.3.4:8888)------B(6.7.8.9:9999), 这就是一个tcp四元组。当tcp连接关闭后,四元组释放。后面的新连接可能会重用到这个四元组(有这个可能性,那么问题就是: 新四元组和旧四元组完全一致,他们的网络包可能会混乱 。)所以,可以考虑这样一个机制:让旧四元组对应的所有网络包都消失后(等一段时间,才允许新四元组建立。所以,TIME_WAIT存在的理由之二是新旧四元组互不干扰。)

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

1、TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。当有一方要关闭连接时,会发送指令告知对方,我要关闭连接了。

2、这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,也就是说,服务端收到客户端的 FIN 标志,知道客户端想要断开这次连接了,但是,我服务端,我还想发数据呢?我等到发送完了所有的数据后,会发送一个FIN 段来关闭此方向上的连接。接收方发送 ACK确认关闭连接。

注意,接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”。

3、客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。

4、因为服务端在 LISTEN 状态下,收到建立连接请求的 SYN 报文后,把 ACK 和 SYN 放在一个报文里发送给客户端。而关闭连接时,当收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定,因此,己方 ACK 和 FIN 一般都会分开发。

TCP、UDP协议的区别

网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。

TCP和UDP的区别:

它们都是传输层协议

1.TCP是面向连接的,发送数据前先要建立连接,数据传输结束后要释放连接;UDP是无连接的,发送数据前不需要建立连接

2.TCP是可靠的,TCP可以保证数据无差错,不重复,不丢失,按序达到;UDP是不可靠的,只能尽最大努力交付。

3.TCP有流量控制、拥塞控制,提供全双工通信;UDP没有拥塞控制。

4.TCP是面向字节流的(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块);UDP是面向报文的(对于应用程序传下来的报文不合并也不拆分,只是添加UDP首部)

5.TCP首部开销大,20个字节;UDP首部开销小,8个字节

6.TCP是点到点通信;UDP支持一对一,一对多,多对一,多对多的交互通信。

7.TCP适用于对网络通讯质量要求高的场景,比如文件传输、发送和接收邮件、远程登录等场景;UDP适用于对网络通讯质量要求不高,要求网络通讯速度尽可能快的场景。比如:QQ语音、QQ视频、直播等等。

UDP和TCP的首部格式

UDP首部字段只有8个字节,包括源端口、目的端口、长度和检验和。12字节的伪首部是为了计算检验和临时添加的。

TCP 首部格式比 UDP 复杂。

序号:用于对字节流进行编号,例如序号为301,表示第一个字节的编号为301,如果携带的数据长度为100字节,那么下一个报文段的序号应为401。

确认号:期望收到的下一个报文段的序号。例如B正确收到A发送来的一个报文段,序号为501,携带的数据长度为200字节,因此B期望下一个报文段的序号为701,B发送给A的确认报文段中确认号就为701。

数据偏移:指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。

控制位:8为从左到右分别是CWR,ECE,URG,ACK,PSH,RST,SYN,FIN

CWR:CWR标志与后面的ECE标志都用于IP首部的ECN字段,ECE标志为1时,则通知对方已将拥塞窗口缩小

ECE:若其值为1则会通知对方,从对方到这边的网络有阻塞。在收到数据包的IP首部中ECN为1时将TCP首部中的ECE设为1

URG:该位设为1,表示包中有需要紧急处理的数据,对于需要紧急处理的数据,与后面的紧急指针有关

ACK:该位设为 1,确认应答的字段有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设为 1;

PSH:该位设为 1,表示需要将收到的数据立刻传给上层应用协议,若设为 0,则先将数据进行缓存;

RST:该位设为 1,表示 TCP 连接出现异常必须强制断开连接;

SYN:用于建立连接,该位设为 1,表示希望建立连接,并在其序列号的字段进行序列号初值设定;

FIN:该位设为 1,表示今后不再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。

每个主机又对对方的 FIN 包进行确认应答之后可以断开连接。不过,主机收到 FIN 设置为 1 的 TCP 段之后不必马上回复一个 FIN 包,而是可以等到缓冲区中的所有数据都因为已成功发送而被自动删除之后再发 FIN 包;

窗口:窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

TCP 短连接和长连接的区别

短连接:Client 向 Server 发送消息,Server 回应 Client,然后一次读写就完成了,这时候双方任何一个都可以发起 close 操作,不过一般都是 Client 先发起 close 操作。短连接一般只会在 Client/Server 间传递一次读写操作。

短连接的优点:管理起来比较简单,建立存在的连接都是有用的连接,不需要额外的控制手段。

长连接:Client 与 Server 完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

在长连接的应用场景下,Client 端一般不会主动关闭它们之间的连接,Client 与 Server 之间的连接如果一直不关闭的话,随着客户端连接越来越多,Server 压力也越来越大,这时候 Server 端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致 Server 端服务受损;如果条件再允许可以以客户端为颗粒度,限制每个客户端的最大长连接数,从而避免某个客户端连累后端的服务。

长连接和短连接的产生在于 Client 和 Server 采取的关闭策略,具体的应用场景采用具体的策略。

TCP粘包、拆包及解决办法

为什么常说 TCP 有粘包和拆包的问题而不说 UDP ?

UDP 是基于报文发送的,而且UDP首部采用了 16bit 来指示 UDP 数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。

而 TCP 是基于字节流的,虽然应用层和 TCP 传输层之间的数据交互是大小不等的数据块,TCP 并没有把这些数据块区分边界,仅仅是一连串没有结构的字节流;另外在TCP 的首部没有表示数据长度的字段,基于上面两点,在使用TCP 传输数据时,才有粘包或者拆包现象发生的可能。

什么是粘包、拆包?

假设 Client 向 Server 连续发送了两个数据包,用 packet1 和 packet2 来表示,那么服务端收到的数据可以分为三种情况,现列举如下:

第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象。

第二种情况,接收端只收到一个数据包,但是这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。这种情况由于接收端不知道这两个数据包的界限,所以对于接收端来说很难处理。

第三种情况,这种情况有两种表现形式,如下图。接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。这两种情况如果不加特殊处理,对于接收端同样是不好处理的。

为什么会发生 TCP 粘包、拆包?

  • 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。
  • 待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。
  • 要发送的数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包。
  • 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。

粘包、拆包解决办法:

由于 TCP 本身是面向字节流的,无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,归纳如下:

  • 消息定长:发送端将每个数据包封装为固定长度(不够的可以通过补 0 填充),这样接收端每次接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。
  • 设置消息边界:服务端从网络流中按消息边界分离出消息内容。在包尾增加回车换行符进行分割,例如 FTP 协议。
  • 将消息分为消息头和消息体:消息头中包含表示消息总长度(或者消息体长度)的字段。
  • 更复杂的应用层协议比如 Netty 中实现的一些协议都对粘包、拆包做了很好的处理。

TCP 可靠传输

TCP的任务是在IP层的不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务。

TCP提供的可靠传输服务就是要保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。TCP使用了校验、序号、确认和重传等机制来达到这个目的。

检验:二进制求和取反

序号:首部的序号字段,用来保证数据能有序提交给应用层。TCP连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。

确认:首部的确认号字段,是期望收到对方的下一个报文段的数据的第一个字节的序号。TCP默认使用累计确认,即TCP只确认数据流中至第一个丢失字节为止的字节。

重传:有两种事件会导致TCP对报文段进行重传:超时和冗余ACK

  • 超时:TCP每发送一个报文段,就对这个报文设置一个计时器。只要计时器设置的重传时间到期但还没有收到确认,就要重传这一报文段。
  • 冗余ACK:超时触发重传存在的一个问题就是超时周期往往太长。发送方可在超时事件发生之前通过注意冗余ACK来较好地检测丢包情况。冗余ACK就是再次确认某个字节的ACK,而发送方之前就已经收到过该字节的确认。TCP规定每当比期望序号大的失序字节到达时,就发送一个冗余ACK,指明下一个期待字节的序号。TCP规定当发送方收到对同一个字节的3个冗余ACK时,就可以认为跟在这个被确认字节之后的那些字节已经丢失。然后发送方执行快重传。

TCP传输怎么确保有序?

-通过序列号字段以及确认字段

1.主机每次发送报文段时,TCP就给报文段数据中每个字节分配一个序列号,首部的序号字段就是记录这个报文段数据中第一个字节的序号,并且在一个特定时间内等待接收主机的确认

2.如果发送主机在一个特定时间内没有收到接收主机的确认(累计确认),则发送主机会重传(超时/冗余ACK)此报文段

3.接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等

4.接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流缓存或者传递到应用层进行处理

TCP滑动窗口

窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。

发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。

接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。

滑动窗口的作用

TCP发送报文,等待对方确认,收到确认后继续发下一个报文,效率会非常低。而有了滑动窗口,通信双方就不用发送一个报文后,收到此报文的确认后再发送下一个报文,而是可以连续发送多个报文,只要别超过窗口大小限制。还有就是,一旦网络拥塞或报文丢失又会造成报文重发,而这些重发又加重了拥塞,所以TCP里要严格控制发送速率防止网络拥塞,滑动窗口根据接收方的窗口大小很好的限制了发送方的发送速率。

总结就是:(1)滑动窗口允许发送方连续发送多个报文(2)根据对方接收窗口大小限制发送方的发送速率,防止拥塞。

(注意:实际中并不一定按对方接收窗口rwnd大小来决定发送速率,因为没有考虑网络拥塞情况。拥塞控制中同样会决定发送窗口cwnd大小,最后发送时取 MIN(cwnd,rwnd))

TCP流量控制

流量控制是为了控制发送方发送速率,保证接收方来得及接收。

接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。

实际上,为了避免此问题的产生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据段仅包含一个字节来获取最新的窗口大小信息。

TCP拥塞控制(拥塞就是网络的负载变大,但是吞吐量变小)

拥塞:有时候网络中负载过大,发送的数据可能会在网络中长时间滞留,就像堵车一样。

拥塞控制:通过慢开始,拥塞控制,快重传,快恢复来拥塞控制。

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。

TCP 主要通过四个算法来进行拥塞控制:

慢开始、拥塞避免、快重传、快恢复。

发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。

为了便于讨论,做如下假设:

  • 接收方有足够大的接收缓存,因此不会发生流量控制;
  • 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。

慢开始与拥塞避免

发送的最初执行慢开始,令 cwnd = 1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 ...

注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始门限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。

如果出现了超时,则令 ssthresh = cwnd / 2,然后重新执行慢开始。

快重传与快恢复

在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。

在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。

在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。

慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。

在浏览器中输入url地址->显示主页的过程

1.先检查输入的url是否合法,然后进行DNS域名解析

  • 在浏览器DNS缓存中搜索
  • 在操作系统DNS缓存中搜索
  • 读取系统hosts文件,查找其中是否有对应的ip
  • 向本地配置的首选DNS服务器发起域名解析请求

2.建立TCP连接

TCP是一个端到端的可靠的面向连接的协议,所以HTTP基于传输层TCP协议不用担心数据的传输的各种问题。

3.发起HTTP请求

4.服务器处理请求并返回HTTP响应报文

5.浏览器解析html

6.浏览器布局渲染

补充:

DNS解析:DNS解析的过程就是寻找哪台机器上有你需要资源的过程。当你在浏览器中输入一个地址时,例如www.baidu,其实不是百度网站真正意义上的地址。互联网上每一台计算机的唯一标识是它的IP地址,但是IP地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其他计算机,也就是上面提到的百度的网址。所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到IP地址的转换,这个过程就是DNS解析。它实际上充当了一个翻译的角色,实现了网址到IP地址的转换。

状态码

100:Continue 表示到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应

200:OK

204:No Content 请求已经处理成功,但是返回的响应报文不包含实体的主体部分,一般只需要从客户端往服务器端发送信息,而不需要返回数据时使用

206:Partial Content 表示客户端进行了范围请求,响应报文包含由Content-Range指定范围的实体内容

301:Moved Permanently 永久性重定向

302:Found 临时性重定向

303:Set Other 和302有着相同的功能,但是303明确要求客户端采用GET方法获取资源

304:Not Modified 如果请求报文首部包含一些条件,比如:If-Modified-Since,如果不满足条件,则服务器会返回304状态码

307:Temporal Redirect 临时性重定向,与302的含义类似,但是307要求浏览器不会把重定向请求的POST方法改成GET方法

400:Bad Request 请求报文中存在语法错误

401:Unauthorized 状态码表示发送的请求需要有认证信息,如果之前已经进行过一次请求,则表示用户验证失败

403:Forbidden 请求被拒绝

404:Not Found 未发现资源

405:Method Not Allowed 方法不允许

500:Internal Server Error 服务器正在执行请求时发生错误

503:Server Unavaliable 服务器暂时处于超负载或者正在停机维护,现在无法处理请求

各种协议与HTTP协议之间的关系

URI和URL的区别是什么?

URI(Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。<scheme><hostname><path>

URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。<协议>://<主机>:<端口>/<路径>

URI的作用像身份证号一样,URL的作用更像家庭住址一样。URL是一种具体的URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。

TCP/IP协议与HTTP协议的区别

TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。在传输数据时,可以只使用传输层协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议。

HTTP请求报文和响应报文

请求报文:

<request-line> //请求行 
<headers> //请求首部 
<blank line> //空行 
<request-body> //请求体

示例:

POST /user HTTP/1.1 //请求行 
Host: www.user Content-Type: application/x-www-form-urlencoded 
Connection: Keep-Alive 
User-agent: Mozilla/5.0. //以上是首部行 
(此处必须有一空行) //空行分割header和请求内容 
name=world 请求体

请求行:由3部分组成:请求方法,请求URL(不包括域名),HTTP协议版本

请求方法比较多:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT

  • GET:传递参数长度受限制,因为传递的参数是直接表示在地址栏中,而特定浏览器和服务器对url的长度是有限制的。因此,GET不适合用来传递私密数据,也不适合拿来传递大量数据。一般的HTTP请求大多使用GET。
  • POST:把传递的数据封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,对数据量没有限制,也不会显示在URL中。
  • HEAD:HEAD和GET相似,不过服务端接收到HEAD请求时只返回响应头,不返回响应内容。所以,如果只需要查看某个页面的状态时,用HEAD更高效,因为省去了传输页面内容的时间。
  • DELETE:删除某一个资源
  • OPTIONS:用于获取当前URL所支持的方法。若请求成功,会在HTTP头中包含一个名为Allow的头,值是所支持的方法,比如GET,POST
  • PUT:把一个资源存放在指定的位置上。本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
  • TRACE:回显服务器收到的请求,主要用于测试或诊断。
  • CONNECT:是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器,通常用于SSL加密服务器的连接与非加密的HTTP代理服务器的通信。

HTTP协议版本:

  • HTTP/1.0:HTTP/1.0支持:GET、POST、HEAD三种HTTP请求方法。
  • HTTP/1.1:HTTP/1.1是当前正在使用的版本。该版本默认采用持久连接,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。HTTP/1.1新增了:OPTIONS、PUT、DELETE、TRACE、CONNECT五种HTTP请求方法。

请求头部:请求头部由关键字/值对组成,每行一对

  • User-Agent : 产生请求的浏览器类型
  • Accept : 客户端希望接受的数据类型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型
  • Content-Type:发送端发送的实体数据的数据类型。比如,Content-Type:text/html(application/json)表示发送的是html类型。
  • Host : 请求的主机名,允许多个域名同处一个IP地址,即虚拟主机

空行:请求头之后是一个空行,通知服务器以下不再有请求头

请求体:请求体不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求体相关的最常使用的是包体类型Content-Type和包体长度Content-Length;

响应报文:

<status-line> //状态行 
<headers> //响应头 
<blank line> //空行 
<response-body> //响应体

状态行:状态行也由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述

HTTP/1.1 200 OK

响应头部:响应头可能包括:

  • Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源;
  • Server:Server 响应报头域包含了服务器用来处理请求的软件信息及其版本。它和 User-Agent 请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件(浏览器)和操作系统的信息。
  • Vary:指示不可缓存的请求头列表;
  • Connection:连接方式;

  对于请求来说:close(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不等待本次连接的后续请求了)。keepalive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求);

  对于响应来说:close(连接已经关闭); keepalive(连接保持着,在等待本次连接的后续请求); Keep-Alive:如果浏览器请求保持连接,则该头部表明希望WEB 服务器保持连接多长时间(秒);例如:Keep-Alive:300;

  • WWW-Authenticate:WWW-Authenticate响应报头域必须被包含在401 (未授权的)响应消息中,这个报头域和前面讲到的Authorization 请求报头域是相关的,当客户端收到 401 响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送一个包含了Authorization 报头域的请求;

空行:最后一个响应头部之后是一个空行,发送回车符和换行符,通知服务器以下不再有响应头部。

响应体:服务器返回给客户端的文本信息;

HTTP工作原理

HTTP 协议采用请求/响应模型。客户端向服务器发送一个请求报文,服务器以一个状态作为响应。

以下是 HTTP 请求/响应的步骤:

  ● 客户端连接到web服务器:HTTP 客户端与web服务器建立一个 TCP 连接;

  ● 客户端向服务器发起 HTTP 请求:通过已建立的TCP 连接,客户端向服务器发送一个请求报文;

  ● 服务器接收 HTTP 请求并返回 HTTP 响应:服务器解析请求,定位请求资源,服务器将资源副本写到 TCP 连接,由客户端读取;

  ● 释放 TCP 连接:若connection 模式为close,则服务器主动关闭TCP 连接,客户端被动关闭连接,释放TCP 连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;

  ● 客户端浏览器解析HTML内容:客户端将服务器响应的 html 文本解析并显示;

HTTP1.0和HTTP1.1的主要区别是什么?

 

HTTP3(QUIC协议)

谷歌决定在UDP基础上改造一个具备TCP协议优点的新协议也就顺理成章了,这个新协议就是QUIC协议。

QUIC其实是Quick UDP Internet Connections的缩写,直译为快速UDP互联网连接。

QUIC的优点:队头阻塞问题;0RTT建链;前向纠错;连接迁移

1.队头阻塞问题

队头阻塞在计算机网络中是一种性能受限的现象,通俗来说就是:一个数据包影响了一堆数据包,它不来大家都走不了。

队头阻塞问题可能存在于HTTP层和TCP层,在HTTP1.x时两个层都存在该问题。HTTP2.0协议的多路复用机制解决了HTTP层的队头阻塞问题,但是在TCP层仍然存在队头阻塞问题。

TCP协议在收到数据包之后,这部分数据可能是乱序达到的,但是TCP必须将所有数据收集排序整合后给上层使用,如果其中某个包丢失了,就必须等到重传,从而出现某个丢包数据阻塞整个连接的数据使用。

QUIC协议是基于UDP协议实现的,在一条链路上可以有多个流,流与流之间是互不影响的,当一个流出现丢包影响范围非常小,从而解决队头阻塞问题。

2.0RTT建链

衡量网络建链的常用指标是RTT,就是数据包一来一回的时间消耗。

RTT包括三部分:往返传播时延、网络设备内排队时延、应用程序数据处理时延。

一般来说HTTPS协议要建立完整链接包括:TCP握手和TLS握手,总计需要至少2-3个RTT,普通的HTTP协议也需要至少1个RTT才可以完成握手。

然而,QUIC协议可以实现在第一个包就可以包含有效的应用数据,从而实现0RTT,但这也是有条件的。

简单来说,基于TCP协议和TLS协议的HTTP2.0在真正发送数据包之前需要花费一些时间来完成握手和加密协商,完成之后才可以真正传输业务数据。

但是QUIC则第一个数据包就可以发业务数据,从而在连接延时有很大优势,可以节约数百毫秒的时间。

QUIC的0RTT也是需要条件的,对于第一次交互的客户端和服务端0RTT也是做不到的,毕竟双方完全陌生。

因此,QUIC协议可以分为首次连接和非首次连接,两种情况进行讨论。

3.前向纠错

前向纠错也叫前向纠错码Forward Error Correction 简称FEC 是增加数据通讯可信度的方法,在单向通讯信道中,一旦错误被发现,其接收器将无权再请求传输。

QUIC每发送一组数据就对这组数据进行异或运算,并将结果作为一个FEC包发送出去,接收方收到这一组数据后根据数据包和FEC包即可进行校验和纠错。

4.连接迁移

网络切换几乎无时无刻不在发生。

五元组:源IP地址,源端口,目的IP地址,目的端口和传输层协议

TCP协议使用五元组来表示一条唯一的连接,当我们从4G环境切换到wifi环境时,手机的IP地址就会发生变化,这时必须创建新的TCP连接才能继续传输数据。

QUIC协议基于UDP实现摒弃了五元组的概念,使用64位的随机数作为连接的ID,并使用该ID表示连接。

基于QUIC协议之下,我们在日常wifi和4G切换时,或者不同基站之间切换都不会重连,从而提高业务层的体验。

HTTP 请求方法

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

GET和POST两种基本请求方法的区别:

1.GET参数通过URL传递,POST放在请求体中

2.GET请求在URL中传送的参数是有长度限制的,而POST没有

3.GET比POST更不安全,因为参数直接暴露在URL中,所以不能用来传递敏感信息

4.GET请求只能只能进行url编码,而POST支持多种编码方式(4种)

5.GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留

6.GET在浏览器回退(后退按钮/刷新)时是无害的,而POST会再次提交请求

7.GET请求产生1个TCP数据包,而POST请求产生2个TCP数据包

8.浏览器在发送GET请求时会将header和data一起发送给服务器,服务器返回200状态码。在发送POST请求时,会先将header发送给服务器,服务器返回100,之后再将data发送给服务器,服务器会返回200(GET请求效率更高)

举例:根据HTTP协议规定,GET方法可以携带交互需要的所有数据,因此你会看到搜索百度或谷歌的时候,点击搜索形成的URL包含了你刚才的搜索关键字,没有安全需求的请求把信息放URL里没关系,但是你访问银行网站的时候,不希望把账户、密码这些放在URL里被人拦截是吧,所以HTTP设计了POST请求,他可以把请求信息放在HTTP请求里,具体格式这里不细说了,这样你就不能简单的从URL里找到账户、密码了。

POST请求编码方式

POST一般用来向服务器端提交数据。

协议规定POST提交的数据必须放在消息主体中(entity-body),但协议没有规定数据必须使用什么编码方式。但是,数据发送出去,还要服务器端解析成功才有意义。

服务器端一般是根据请求头(header)中的content-type字段来获知请求中的消息主体是用何种方式编码的,然后再对主体进行解析。POST提交数据中,包含了content-type和消息主体编码方式两部分。

4种常见的POST提交数据方式:

  • application/x-www-form-urlencoded

这应该是最常见的 POST 提交数据的方式了。浏览器的原生 form 表单,如果不设置 enctype属性,那么最终就会默认以 application/x-www-form-urlencoded 方式提交数据。

在POST提交数据中Content-Type 被指定为 application/x-www-form-urlencoded;提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。很多时候,我们用 Ajax 提交数据时,也是使用这种方式。

xhr.open("POST","http://www.example",true); 
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  • multipart/form-data

这也是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 form 的 enctype 等于这个值。这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。上面提到的这两种 POST 数据的方式,都是浏览器原生支持的。

xhr.open("POST","http://www.example",true); 
xhr.setRequestHeader("Content-Type", "multipart/form-data");
  • application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

xhr.open("POST","http://www.example",true); 
xhr.setRequestHeader("Content-Type", "application/json");
  • text/xml

它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范,它的使用也很广泛,能很好的支持已有的 XML-RPC 服务。不过,XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。

xhr.open("POST","http://www.example",true); 
xhr.setRequestHeader("Content-Type", "text/xml");

HTTP长连接、短连接

在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:

Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

HTTP是不保存状态的协议,如何保存用户状态?

HTTP无状态:协议对交互场景没有记忆能力。浏览器对服务器完成一次资源请求后,再次对服务器进行资源请求,服务器不会记得之前的行为。

那么我们保存用户状态呢?:Session和Cookie

cookie:第一次登录后服务器会返回一些数据(cookie,其中就包含了session_id)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB,因此使用cookie只能存储一些小量的数据。

session:session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器中,而session存储在服务器中。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。

cookie和session结合使用:

  • 存储在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中的。如果用户已经登录,则浏览器会在cookie中保存一个session_id,下次再次请求的时候,就会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据,就能知道该用户到底是谁,以及之前保存的一些状态信息,这种专业术语叫做server side session。如果客户端的浏览器禁用了 Cookie 怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
  • 将session数据加密,然后存储在cookie中,这种专业术语叫做client side session,flask采用的就是这种方式。

cookie的工作原理:

(1)浏览器端第一次发送请求到服务器端

(2)服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端

(3)浏览器端再次访问服务器端时会携带服务器端创建的Cookie

(4)服务器端通过Cookie中携带的数据区分不同的用户

Session的工作原理:

(1)浏览器端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie(name为JSESSIONID的固定值,value为session对象的ID),然后将该Cookie发送至浏览器端

(2)浏览器端发送第N(N>1)次请求到服务器端,浏览器端访问服务器端时就会携带该name为JSESSIONID的Cookie对象

(3)服务器端根据name为JSESSIONID的Cookie的value(sessionId),去查询Session对象,从而区分不同用户。

name为JSESSIONID的Cookie不存在(关闭或更换浏览器),返回1中重新去创建Session与特殊的Cookie

name为JSESSIONID的Cookie存在,根据value中的SessionId去寻找session对象

value为SessionId不存在**(Session对象默认存活30分钟)**,返回1中重新去创建Session与特殊的Cookie

value为SessionId存在,返回session对象

Cookie和Sessin有什么区别?

共同之处:cookie和session都是用来跟踪浏览器用户身份的会话方式。

区别:

1.cookie数据存放在客户的浏览器上,容易被恶意查看;session数据放在服务器上。

2.cookie只能存储 ASCII 码,而session可以存储任何类型的数据。

3.session的运行依赖session id,而session id存于cookie中,叫做JSESSIONID。如果浏览器禁用了cookie,同时session也会失效(可以通过其他方式实现,比如在url中传递seesion id)。

4.单个cookie在客户端的限制是4K,很多浏览器对于保存的cookie个数是有限制的(一般是20个)。

5.cookie对客户端是可见的,别有用心的人可以分析放在本地的cookie并进行欺骗,所以它是不安全的;session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。

6.开发可以通过设置cookie的属性,达到使cookie长期有效的效果;session依赖于名为ISESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。

7.cookie保管在客户端,不占用服务器资源,对于并发用户十分多的网站,cookie是好的选择;session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。

8.cookie支持跨域名访问;session不支持跨域名访问。

HTTP和HTTPS

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

为了解决HTTP协议这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份并为浏览器和服务器之间的通信加密。HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。

区别:

HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是就设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。

HTTPS和HTTP的区别主要如下:

1、https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。

2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

3、http和https使用的默认端口不一样,前者是80,后者是443。

4、http的连接很简单,是无状态的;https协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

5、HTTP直接通过明文在浏览器和服务器之间传递信息;HTTPS采用对称加密以及非对称加密结合的方式来保护浏览器和服务器之间的通信安全。(对称加密算法加密数据+非对称加密算法加密密钥+数字证书验证身份=安全

HTTPS的工作原理:

1.客户使用https的url访问web服务器,要求与web服务器建立ssl连接

2.web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端

3.客户端的浏览器与web服务器开始协商ssl连接的安全等级,也就是信息加密的等级

4.客户端的浏览器会根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站

5.web服务器利用自己的私钥解密出会话密钥

6.web服务器利用会话密钥加密与客户端之间的通信

HTTPS的优点:

尽管HTTPS并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但HTTPS仍是现行架构下最安全的解决方案,主要有以下几个好处:

1.使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;

2.HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。

3.HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

4.谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。

HTTPS的缺点:

虽然说HTTPS有很大的优势,但其相对来说,还是存在不足之处的:

1.HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;

2.HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;

3.SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。

4.SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。

5.HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。

HTTP切换到HTTPS

这里需要将页面中所有的链接,例如js,css,图片等等链接都由http改为https。例如:http://www.baidu改为https://www.baidu,但是,这里虽然将http切换为了https,还是建议保留http。所以我们在切换的时候可以做http和https的兼容,具体实现方式是,去掉页面链接中的http头部,这样可以自动匹配http头和https头。例如:将http://www.baidu改为//www.baidu。然后当用户从http的入口进入访问页面时,页面就是http,如果用户是从https的入口进入访问页面,页面即使https的。

对称加密与非对称加密

对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;

优点:简单快捷;密钥较短;且破译困难

缺点:如果用户一旦多的话,管理密钥也是一种困难。不方便直接沟通的两个用户之间怎么确定密钥也需要考虑,这其中就会有密钥泄露的风险,以及存在更换密钥的需求。

非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。

优点:比对称加密安全

缺点:加解密比对称加密耗时

但是非对称加密也是存在漏洞,因为公钥是公开的,如果有C冒充B的身份利用A的公钥给A发消息,这样就会乱套,所以接下来就采用非对称加密+摘要算法+数字签名的机制来确保其传输安全。

Hash算法(摘要算法)

Hash算法的特点是单向不可还原,用户可以通过hash算法对目标信息生成一段特定长度的唯一hash值,却不能通过这个hash值重新获得目标信息。因此hash算法常用在不可还原的密码储存、信息完整性校验等。只要源数据不同,算法得到的摘要必定不同。

数字签名

数字签名用来,保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。

数字签名是 A将原始明文通过 hash 算法得到摘要,这个摘要是不可逆的;将明文加密,连同摘要一起发送给B;B接收到后解密,得到这个摘要 a 和加密的明文,再将加密明文解密得到原始明文,然后通过同一 hash 算法得到新的摘要 b,比较 a 与 b 就可得知在传输过程中是否被更改过。

因此数字签名能够验证信息的完整性。如果中途数据被纂改或者丢失。那么对方就可以根据数字签名来辨别是否是来自对方的第一手信息数据。

更多推荐

计算机网络常见面试题整理

本文发布于:2023-04-21 08:22:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/49ff3eaed402681233f7581382e8a1b0.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:计算机网络   面试题   常见

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 92849文章数
  • 23616阅读数
  • 0评论数