小猿的某同事不甘于现状,近期到处投简历面试。某天,小猿只见某灰头土脸、唉声叹气,于是小猿本着看热闹不嫌事儿大的心态,一脸坏笑凑上去问:“大佬,最近面试咋样,是不是都拿好几个offer了~^_^”,某答道:“什么呀,面个试咋就这么难,一道面试题硬是让面试官扯出了整个计算机网络知识图谱,也是没谁了~”,小猿好奇问:“啥题,啥题~”,某答:“烂大街的一道题,面试前也准备了,唉,你说为啥面试官就能从这道题目扯出一堆题目...”(此处省略一万字)
接下来小猿就给大家说说某遇到的这道题,还有它牵扯出的整个计算机网络的知识图谱。废话不多说,直接上题目
题目描述一:请说说HTTP请求的整个过程
题目描述二:当你在浏览器中输出某个URL,按下回车后都经历了什么样的流程
题目描述三:请简单介绍一下HTTP是怎么工作的
相信各位猿对这道题应该并不陌生,而且网上一搜一堆的讲解与答案,但是某遇到的这个大牛面试官,却可以从某的回答中延伸出更多的问题,如果想要过关,还是要对整个计算机网络的知识体系有比较深刻的理解才行。下面先贴出小猿对这个题目的理解和可能从这道题目引出的计算机网络的知识点,然后小猿对这些知识点慢慢的给大家分析。
小猿对题 目的理解:
DNS解析:如果URL中是网址,需要向对这个网址进行域名解析,得到相应的IP地址,请求会逐层查询DNS缓存得到目的IP地址(DNS缓存由近到远依次是:浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、根域名服务器缓存、顶级域名服务器缓存)
TCP连接:根据IP地址和断开,找到对应的服务器,通过TCP的三次握手建立连接
发送HTTP请求:建立TCP连接后发起HTTP请求
服务器处理请求并返回HTTP报文:服务器根据请求参数得到返回结果,并返回HTTP报文
浏览器解析渲染页面:浏览器得到报文,解析HTML代码,并请求HTML代码中的资源(例如js、css等),然后渲染页面
连接结束:TCP4次挥手,HTTP断开连接
知识图谱
OSI七层架构
七层结构简介:
7层结构数据传输流程:
详细介绍每层的功能和
应用层(Application Layer)
是计算机用户,以及各种应用程序和网络之间的接口:
是用户与网络,以及应用程序与网络间的直接接口,使得用户能够与网络进行交互式联系。
实现各种服务:该层具有的各种应用程序可以完成和实现用户请求的各种服务。
该层还负责协调各个应用程序间的工作。
应用层为用户提供的服务和协议有:文件服务、目录服务、文件传输服务(FTP)、远程登录服务(Telnet)、电子邮件服务(E-mail)、打印服务、安全服务、网络管理服务、数据库服务等。
表示层(Presentation Layer)
对来自应用层的命令和数据进行解释,对各种语法赋予相应的含义,并按照一定的格式传送给会话层。
主要功能:数据格式处理、编码、压缩解压、加密解密等,具体说明如下:
数据格式处理:协商和建立数据交换的格式,解决各应用程序之间在数据格式表示上的差异。
数据的编码:处理字符集和数字的转换。例如由于用户程序中的数据类型(整型或实型、有符号或无符号等)、用户标识等都可以有不同的表示方式,因此,在设备之间需要具有在不同字符集或格式之间转换的功能。
压缩和解压缩:为了减少数据的传输量,这一层还负责数据的压缩与恢复。
数据的加密和解密:可以提高网络的安全性。
-
会话层(Session Layer)
其任务就是组织和协调两个会话进程之间的通信,并对数据交换进行管理,具体如下:
会话管理:允许用户在两个实体设备之间建立、维持和终止会话,并支持它们之间的数据交换。例如提供单方向会话或双向同时会话,并管理会话中的发送顺序,以及会话所占用时间的长短。
会话流量控制:提供会话流量控制和交叉会话功能。
寻址:使用远程地址建立会话连接。
出错控制:从逻辑上讲会话层主要负责数据交换的建立、保持和终止,但实际的工作却是接收来自传输层的数据,并负责纠正错误。会话控制和远程过程调用均属于这一层的功能。但应注意,此层检查的错误不是通信介质的错误,而是磁盘空间、打印机缺纸等类型的高级错误。
传输层(Transport Layer)
向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。传输层的作用是向高层屏蔽下层数据通信的细节,即向用户透明地传送报文。
传输连接管理:提供建立、维护和拆除传输连接的功能。传输层在网络层的基础上为高层提供“面向连接”和“面向无接连”的两种服务。
处理传输差错:提供可靠的“面向连接”和不太可靠的“面向无连接”的数据传输服务、差错控制和流量控制。在提供“面向连接”服务时,通过这一层传输的数据将由目标设备确认,如果在指定的时间内未收到确认信息,数据将被重发。
监控服务质量。
该层常见的协议:TCP/IP中的TCP协议、Novell网络中的SPX协议和微软的NetBIOS/NetBEUI协议。
网络层(Network Layer)
通过路由选择算法,为报文或分组通过通信子网选择最适当的路径
数据链路层的数据在这一层被转换为数据包,然后通过路径选择、分段组合、顺序、进/出路由等控制,将信息从一个网络设备传送到另一个网络设备。
寻址:数据链路层中使用的物理地址(如MAC地址)仅解决网络内部的寻址问题。在不同子网之间通信时,为了识别和找到网络中的设备,每一子网中的设备都会被分配一个唯一的地址。由于各子网使用的物理技术可能不同,因此这个地址应当是逻辑地址(如IP地址)。
交换:规定不同的信息交换方式。常见的交换技术有:线路交换技术和存储转发技术,后者又包括报文交换技术和分组交换技术。
路由算法:当源节点和目的节点之间存在多条路径时,本层可以根据路由算法,通过网络为数据分组选择最佳路径,并将信息从最合适的路径由发送端传送到接收端。
连接服务:与数据链路层流量控制不同的是,前者控制的是网络相邻节点间的流量,后者控制的是从源节点到目的节点间的流量。其目的在于防止阻塞,并进行差错检测。
数据链路层是解决同一网络内节点之间的通信,而网络层主要解决不同子网间的通信。例如在广域网之间通信时,必然会遇到路由(即两节点间可能有多条路径)选择问题。
数据链路层(Data Link Layer)
物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法。
该层通常又被分为介质访问控制(MAC)和逻辑链路控制(LLC)两个子层
MAC子层的主要任务是解决共享型网络中多用户对信道竞争的问题,完成网络介质的访问控制;
LLC子层的主要任务是建立和维护网络连接,执行差错校验、流量控制和链路控制。数据链路层的具体工作是接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传输。
物理层(Physical Layer)
利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么。
分享一张大而全的七层协议框架图
TCP/IP协议-OSI的一种“实现”
传输控制协议TCP简介
面向连接的、可靠的、基于字节流的传输层通信协议
将应用的数据流分割成报文段并发送个给目标节点的TCP层,
分段的长度受数据链路层MTU(最大传输单元,Maximum Transmission Unit)的限制
TCP单个数据报的最大长度称为最大段尺寸MSS;
在TCP三次握手建立连接的时候,双方会商量传输中MSS的大小;
数据包都有序号以保证消息接收的顺序,对方收到则发送ACK确认,未收到则重传
使用奇偶校验和来校验数据在传输过程中是否有误
TCP报文头
-
SourcePort:源端口,占用2个字节。源端口和IP地址的作用是标识报文的返回地址。
p.s. IP可以唯一表示一台主机,TCP协议和端口号可以唯一表示主机中的一个进程;所以我们可以根据IP地址+协议+端口号唯一表示网络中的一个进程(即Socket的工作原理)。
DestinationPort:目的端口,占用2个字节;指明接收方计算机上的应用程序的端口。
SequenceNumber(序号seq):本报文段发送的数据组的第一个字节的序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。
AcknowledgmentNumber(确认号ack):指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。
offset(数据偏移):占用4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。
Reserved(保留字节):为将来定义新的用途保留,现在一般置0。
TCP Flags(TCP控制位)
SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。
PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
CWR:Congestion Window Reduced
ECE:ECN echo
Window(窗口):滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。
Checksum(校验和):奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16位进行计算所得。由发送端计算和存储,并由接收端进行验证。
UrgentPointer(紧急指针):只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
TCP Options(选项与填充)如果没有选项,则TCP头长度是20字节,TCP选项最大是40个字节。最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
Data(数据部分)TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。
说说TCP的三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接
第一次握手:建立连接时,客户端发送SYN包到服务器,并进入SYN_SEND状态,等待服务器确认。这里发送的SYN包,SYN标志位为1,seq序号初始为x
第二次握手:服务器收到SYN包,必须确认客户的SYN,同时自己也发送一个SYN包给客户端,此时服务端进入SYN_RECV状态。这里服务端发送的SYN包中SYN标志位和ACK标志位都是1,seq序号初始为y,ack为x+1(表示客户端下次再发送包seq从x+1开始)
第三次握手:客户端收到服务器的SYN+ACK的包,向服务器发送确认包,此包ACK标志位1,seq序号为x+1,ack为y+1(表示服务端下一次发送数据seq从y+1开始)。此包发送完毕,客户端和服务器端都进入ESTABLISHED状态,完成三次握手,开始数据传送。
为什么需要三次握手才能建立连接
为了初始化SequenceNumber
为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
三次握手的隐患-SYN Flood
问题描述
Server收到Client的SYN,回复SYN-ACK的时候未收到ACK确认
Server不断重试直至超时,Linux默认等待63秒才断开连接(Linux默认重试5次,每次等待时间翻倍,第一次重试前等待时间为1秒,第五次重试后等待时间是32秒,然后才断开连接)
恶意攻击者,不断向服务端发送SYN请求后立刻下线,服务器端会等待63秒后才断开连接,进而导致服务端资源耗尽,让正常的连接请求不能处理
针对SYN Flood的防护措施
针对上述问题的解决办法
SYN队列满后,通过tcp_syncookies参数回发SYN Cookie
如果是正常连接,Client会回发SYN Cookie给服务端;如果是恶意攻击,因为Client已经下线,则不会返回。
正常连接返回SYN Cookie后,可以直接建立连接
建立连接后,Client出现故障怎么办
保活机制
向对方发送保活探测报文,如果未收到响应则继续发送
尝试次数达到保活探测数仍未收到响应,则中断连接
TCP四次挥手
挥手是为了终止连接,TCP采用四次挥手来释放连接
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN-WAIT_1状态;
第二次挥手:Server收到FIN后,发送一个ACK给client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态;Client接收到Server的FIN之后,进入FIN_WAIT_2状态;
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态;
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次握手
为什么要有TIME_WAIT状态
防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)
可靠的关闭TCP连接。为的是确认服务器端是否收到客户端发出的ACK确认报文。当客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。MSL指的是Maximum Segment Lifetime:一段TCP报文在传输过程中的最大生命周期。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。
服务器端在1MSL内没有收到客户端发出的ACK确认报文,就会再次向客户端发出FIN报文;
如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时;
否则客户端在2MSL内没有再次收到来自服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段,完成“四次挥手”。
为什么需要四次握手
因为全双工,发送方和接收方都需要FIN报文和ACK保报文
建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。
服务器出现大量CLOSE_WAIT状态的原因
如果一直保持在CLOSE_WAIT状态,那么只有一种情况,就是在对方关闭连接之后服务器程序自己没有进一步发出ack信号。换句话说,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直被程序占着。
检查代码,特别是释放资源的代码
检查配置,特别是处理请求的线程配置
UDP报文结构
UDP 报文中每个字段的含义如下:
源端口:这个字段占据 UDP 报文头的前 16 位,通常包含发送数据报的应用程序所使用的 UDP 端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选的,所以发送端的应用程序不一定会把自己的端口号写入该字段中。如果不写入端口号,则把这个字段设置为 0。这样,接收端的应用程序就不能发送响应了。
目的端口:接收端计算机上 UDP 软件使用的端口,占据 16 位。
长度:该字段占据 16 位,表示 UDP 数据报长度,包含 UDP 报文头和 UDP 数据长度。因为 UDP 报文头长度是 8 个字节,所以这个值最小为 8。
校验值:该字段占据 16 位,可以检验数据在传输过程中是否被损坏。
UDP特点
面向非连接
不维护连接状态,支持同时向多个客户端传输相同的消息
数据包报头只有8个字节,额外开销较小
吞吐量只受限于数据生成速率、传输速率以及机器性能
尽最大努力交付,不保证可靠交付,不需要维护复杂的连接状态表
面向报文,不对应用程序提交的报文信息进行拆分或者合并
TCP和UDP的区别
可以从以下几个方面总结区别
TCP的滑动窗口
窗口数据的计算过程
左边是TCP发送端缓冲区,右边是接收端缓冲区,左边向右边发送数据;从发送端看,下面的长条代表发送的字节流,从左向右依次发送;从接收端看,下面的长条代表接收字节流,从左向右一次接收。
LastByteAcked:指向已经接收到ack反馈的连续内存的最大位置,LastByteAcked之前字节都已经接收到接收端的ack回执
LastByteSent:指向已经发送的最后一个字节的位置
LastByteWrittten:指向上层应用已写完的最大内存位置
LastByteRead:指向上层已经读完的最后一个字节的位置
NextByteExpected:指向已经收到的连续内存的最大位置,已经收到了但是还没有返回ack回执
LastByteRcvd:指向已经接收到的最大内存的位置,NextByteExpected与LastByteRcvd之间存在没有接收到的seq
接收端可接收窗口 AdvertisedWindow 大小:
AdvertisedWindow = MaxRevBuffer - (LastByteRcvd - LastByteRead)
发送端窗口内剩余可发送的窗口 EffectiveWindow 大小:
EffectiveWindow = AdvertisedWindow - (LastByteSent - LastByteAcked)
这样计算是做最坏的打算,就是认为发送端已经接收到回执的连续最大内存到已经发送的最大内存位置的数据,还在路上没有被接收端接收;接收端的最大接收位置的都已经发送了ack,但是还没有被上层应用处理。【这里AdvertisedWindow是接收端反馈给接收端的报文头里window的值,告诉发送端接收端还可以接收多少数据;发送端根据window大小计算自己还可以发送多少数据】
TCP会话的发送方
TCP发送方,任何时候在其缓存内的数据都可以分为四类
Category #1:已经发送并且已经收到ack回执的部分
Category #2:已经发送但是没有收到ack回执的部分;这部分大小是LastByteSent 与LastByteAcked的差
Category #3:已经准备好并且允许发送,但是还没有发送的部分;这部分就是EffectiveWindow 的大小
Category #4:不允许发送的部分;已经准备好的数据,但是由于接收端缓存限制暂时不能发送的部分
其中Category #2 和 Category #3 组成了滑动窗口,当LastByteAcked向前移动的时候,滑动窗口才能向前移动。
TCP会话的接收方
TCP接收方,任何时候在其接收缓存内的数据都可以分为三类或叫三种状态
Category #1+#2:已经接收并且已经回执ack
Category #3:未接收但是可以接收,准备接收的
Category #4:不能接收,达到了窗口的阈值了,不能接收了
因为接收到的数据TCP机制会立刻ack回执,认为没有延迟,所以不存在已接收但没有回执ack的状态;
未接收但是准备接收的 Category #3 就是叫做接收窗口;接收窗口的滑动机制与发送发一致
TCP的滑动窗口总结
TCP最基本的传输可靠性来源于确认重传机制,TCP的滑动窗口的可靠性也是建立在确认重传机制的基础上的;发送窗口只有接收到接收端对本段发送窗口内字节的ack确认,才会滑动发送窗口的左边界;接收窗口只有在前面的端都确认的情况下,才移动左边界,当前面字节没有接收但是接收到后面的字节的情况下,窗口是不会移动的,并且不会对接收到的后边的字节确认,以此让对端确认这些字段是否需要重传。
滑动窗口可以按照一定的策略动态的挑战,应用程序可以根据自身的处理能力设置调整策略
HTTP简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
HTTP工作原理
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。
Web服务器根据接收到的请求后,向客户端发送响应信息。HTTP默认端口号为80,但是你也可以改为8080或者其他端口。
HTTP三点注意事项:
HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP请求结构
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
HTTP响应报文
实例
下面实例是一点典型的使用GET来传递数据的实例:
客户端请求:
GET /hello.txt HTTP/1.1 User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3 Host: www.example.com Accept-Language: en, mi
服务端响应:
HTTP/1.1 200 OK Date: Mon, 27 Jul 2009 12:28:53 GMT Server: Apache Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT ETag: "34aa387-d-1568eb00" Accept-Ranges: bytes Content-Length: 51 Vary: Accept-Encoding Content-Type: text/plain
面试题:在浏览器地址栏键入URL,按下回车之后经历的流程
DNS解析:如果URL中是网址,需要向对这个网址进行域名解析,得到相应的IP地址,请求会逐层查询DNS缓存得到目的IP地址(DNS缓存由近到远依次是:浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、根域名服务器缓存、顶级域名服务器缓存)
TCP连接:根据IP地址和断开,找到对应的服务器,通过TCP的三次握手建立连接
发送HTTP请求:建立TCP连接后发起HTTP请求
服务器处理请求并返回HTTP报文:服务器根据请求参数得到返回结果,并返回HTTP报文
浏览器解析渲染页面:浏览器得到报文,解析HTML代码,并请求HTML代码中的资源(例如js、css等),然后渲染页面
连接结束:TCP4次挥手,HTTP断开连接
HTTP状态码
状态码分类
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
1xx:指示信息--表示请求已接收,继续处理
2xx:请求成功-表示请求已经成功接收、理解、接受
3xx:重定向--要完成请求必须进行更进一步的操作
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误-服务器未实现合法的请求
常见的状态码:
HTTP 请求方法
GET与POST请求的区别
HTTP报文层面:一般情况,GET将请求信息放在URL,POST放在请求体里面
数据层面:GET符合幂等性和安全性,POST不符合
GET请求可以被缓存,被存储,POST不行
Cookie、Session、token
https://www.cnblogs.com/moyand/p/9047978.html
https://segmentfault.com/a/1190000017831088
Cookie
Cookie指的是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能
cookie由服务器生成,发送给浏览器,浏览器把cookie以kv的形式保存到某个目录的文本文件内,下一次请求同一网址时会把该cookie发送给服务端。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量有限
cookie的设置和发送过程:
Session
session从字面上讲,就是会话,就是服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发送请求,都带上这个标识,服务器就知道这个请求来源于谁。浏览器默认采用cookie来保存这个标识。
服务器使用session把用户信息临时保存在服务器上,用户离开网站后session会被销毁。
注意
cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中
现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用
用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。
如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大
Token
token 也称作令牌,由uid+time+sign[+固定参数]
token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景. 所谓无状态就是服务端并不会保存身份认证相关的数据。
token 的认证流程与cookie很相似
用户登录,成功后服务器返回Token给客户端。
客户端收到数据后保存在客户端
客户端再次访问服务器,将token放入headers中
服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码
分布式情况下的session和token
我们已经知道session时有状态的,一般存于服务器内存或硬盘中,当服务器采用分布式或集群时,session就会面对负载均衡问题。
负载均衡多服务器的情况,不好确认当前用户是否登录,因为多服务器不共享session。这个问题也可以将session存在一个服务器中来解决,但是就不能完全达到负载均衡的效果。
而token是无状态的,token字符串里就保存了所有的用户信息
客户端登陆传递信息给服务端,服务端收到后把用户信息加密(token)传给客户端,客户端将token存放于localStroage等容器中。客户端每次访问都传递token,服务端解密token,就知道这个用户是谁了。通过cpu加解密,服务端就不需要存储session占用存储空间,就很好的解决负载均衡多服务器的问题了。这个方法叫做JWT(Json Web Token)
总结
session存储于服务器,可以理解为一个状态列表,拥有一个唯一识别符号sessionId,通常存放于cookie中。服务器收到cookie后解析出sessionId,再去session列表中查找,才能找到相应session。依赖cookie
cookie类似一个令牌,装有sessionId,存储在客户端,浏览器通常会自动添加。
token也类似一个令牌,无状态,用户信息都被加密到token中,服务器收到token后解密就可知道是哪个用户。需要开发者手动添加。
jwt只是一个跨域认证的方案
HTTPS
https://zhuanlan.zhihu.com/p/27395037
//www.greatytc.com/p/14cd2c9d2cd2
HTTPS 协议(HyperText Transfer Protocol over Secure Socket Layer):可以理解为HTTP+SSL/TLS, 即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL,用于安全的 HTTP 数据传输。
如上图所示 HTTPS 相比 HTTP 多了一层 SSL/TLS
SSL(Secure Socket Layer,安全套接字层):SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。
TLS(Transport Layer Security,传输层安全):其前身是 SSL,目前使用最广泛的是TLS 1.1、TLS 1.2。
SSL/TLS 为网络通信提供安全及数据完整性的一种安全协议
SSL/TLS 是操作系统对外的API,SSL3.0后更新为TLS
SSL/TLS 采用身份验证和数据加密保证网络通信的安全和数据的完整性
加密算法:
对称加密:加密和解密都是使用的同一个密钥
有流式、分组两种
例如:DES、AES-GCM、ChaCha20-Poly1305等
非对称加密:加密使用的密钥和解密使用的密钥是不相同的
加密解密的秘钥分别称为:公钥、私钥
公钥和算法都是公开的,私钥是保密的。非对称加密算法性能较低,但是安全性超强,由于其加密特性,非对称加密算法能加密的数据长度也是有限的。
例如:RSA、DSA、ECDSA、 DH、ECDHE
哈希算法
将任意长度的信息转换为较短的固定长度的值,通常其长度要比信息小得多,且算法不可逆。
例如:MD5、SHA-1、SHA-2、SHA-256 等
数字签名
签名就是在信息的后面再加上一段内容(信息经过hash后的值),可以证明信息没有被修改过。hash值一般都会加密后(也就是签名)再和信息一起发送,以保证这个hash值不被修改。
HTTPS数据传输流程
HTTPS在传输的过程中会涉及到三个密钥:
服务器端的公钥和私钥,用来进行非对称加密
客户端生成的随机密钥,用来进行对称加密
一个HTTPS请求实际上包含了两次HTTP传输,可以细分为8步。
客户端向服务器发起HTTPS请求,将浏览器支持的加密算法发送给服务器
服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。
服务器选择一套浏览器支持的加密算法,以证书的形式发送给客户端,其中包含服务端的公钥。
客户端收到服务器端的证书之后,会对证书进行检查,验证其合法性,如果发现发现证书有问题,那么HTTPS传输就无法继续。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。
客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。
服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密、验证哈希,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。
然后服务器将加密后的密文发送给客户端。
客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。
问题:
1.怎么保证保证服务器给客户端下发的公钥是真正的公钥,而不是中间人伪造的公钥呢?
SSL 证书,权威证书机构发布CA证书
2.证书如何安全传输,被掉包了怎么办?
首先,数字证书内容是加密的
包括了加密后服务器的公钥、权威机构的信息、服务器域名,还有经过CA私钥签名之后的证书内容(经过先通过Hash函数计算得到证书数字摘要,然后用权威机构私钥加密数字摘要得到数字签名),签名计算方法以及证书对应的域名。
验证证书过程是安全的
当客户端收到这个证书之后,使用本地配置的权威机构的公钥对证书进行解密得到服务端的公钥和证书的数字签名,数字签名经过CA公钥解密得到证书信息摘要。
然后证书签名的方法计算一下当前证书的信息摘要,与收到的信息摘要作对比,如果一样,表示证书一定是服务器下发的,没有被中间人篡改过。因为中间人虽然有权威机构的公钥,能够解析证书内容并篡改,但是篡改完成之后中间人需要将证书重新加密,但是中间人没有权威机构的私钥,无法加密,强行加密只会导致客户端无法解密,如果中间人强行乱修改证书,就会导致证书内容和证书签名不匹配。
HTTPS和HTTP的区别
HTTPS需要到CA申请证书,HTTP不需要
HTTPS密文传输,HTTP明文传输
连接方式不同,HTTPS默认使用443端口,HTTP默认80
HTTPS=HTTP+加密+认证+完整性保护,较HTTP安全
Socket简介
socket是对TCP/IP协议的抽象,是操作系统对外开放的接口
Socket通信流程
客户端:
4.用户创建socket
5.用户打开socket,并通过IP地址+端口号试图connect服务器的socket
7.客户端连接成功,开始向服务器输入状态信息
9.客户端写入信息
11.客户端关闭
服务器:
1.服务器根据地址类型(ipv4、ipv6)、socket类型、协议创建socket
2.服务器为socket绑定对应的IP地址和端口号
3.服务器监听端口号请求,接收用户发来的连接请求,此时服务器没有打开socket
6.服务器接收到了用户发来的socket连接请求,被动打开socket,开始接收客户端请求,直到用户返回连接信息。这时候服务器的socket进入堵塞状态,所谓堵塞,即accept();方法一直接收到客户端返回连接信息后才返回,然后开始接收下一个用户端请求
8.服务器accept();方法返回,连接成功
10.服务器读取信息
12.服务端关闭
完成~
小猿同事面试过程中,计算机网络相关的基础知识也就问了这么多,肯定还是有很多知识点和细节没有介绍到,小猿和同事们还需要继续努力深究,争取再整理更详细的知识点分析给大家~