此文属于个人收集网络博客等资料以供个人复习用,如有侵权请联系!谢谢
在计算机网络中,网络层位于传输层下面,这是因为它们在网络协议栈中承担不同的功能。具体而言,传输层负责端到端的可靠传输,而网络层则负责将数据包从源主机传输到目的主机,并在网络中进行路由选择和转发。
传输层和网络层之间的主要区别在于它们所涉及的地址范围和数据单元。传输层的端口号是主机到主机的,它用于标识一个应用程序。而网络层使用的是网络地址,它用于标识一个主机或子网。此外,传输层传输的数据单元是数据段,而网络层传输的数据单元是数据包。
因此,在网络协议栈中,传输层和网络层之间存在着明确的功能分工,且数据单元和地址范围不同,它们都扮演着不同但互相配合的角色,使得整个协议栈能够高效、可靠地运行。所以,网络层位于传输层下面是很合理的。
思路: 这道题主要考察候选人,计算机网络体系结构这个基础知识点。计算机网路体系结构呢,有三层:ISO七层模型、TCP/IP四层模型、五层体系结构。大家可以记住这个图,如下:
HTTP
、 FTP
、 SMTP
、 SNMP
、DNS
。TCP
、UDP
。ICMP
、IGMP
、IP
等。POST
和GET
有哪些区别?思路: 这道题主要考察的知识点是POST和GET的区别,可以从数据包、编码方式、请求参数、收藏为书签、历史记录、安全性
等几方面去回答哈。
请求方式 | TCP | UDP |
---|---|---|
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。 |
历史 | 参数保留在浏览器历史中。 | 参数不会保存在浏览器历史中。 |
编码类型 | application/x-www-form-urlencoded | application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。 |
对数据长度的限制 | 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 | 无限制。 |
对数据类型的限制 | 只允许 ASCII 字符。 | 没有限制。也允许二进制数据。 |
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET ! | POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。 |
POST 可能发送两个数据包:
大多数框架都是尽量在一个tcp包里面把HTTP请求发出去的,但是也确实存在先发HTTP头,然后发body的框架。但是具体发多少个TCP包,这个是代码的问题,是tcp协议栈的问题,跟HTTP没关系。
(ref:https://blog.csdn.net/zerooffdate/article/details/81513717)
思路: 这道题实际上考察的知识点是HTTPS的工作流程,大家需要回答这几个要点,公私钥、数字证书、加密、对称加密、非对称加密。
HTTPS = HTTP + SSL/TLS,也就是用SSL/TLS对数据进行加密和解密,Http进行传输。
SSL,即Secure Sockets Layer
(安全套接层协议),是网络通信提供安全及数据完整性的一种安全协议。
TLS,即Transport Layer Security
(安全传输层协议),它是SSL3.0的后续版本。
Https工作流程
客户端
发起Https请求,连接到服务器
的443`端口。服务器
必须要有一套数字证书(证书内容有公钥
、证书颁发机构
、失效日期
等)。服务器
将自己的数字证书发送给客户端
(公钥在证书里面,私钥由服务器持有)。客户端
收到数字证书之后,会验证证书的合法性。如果证书验证通过,就会生成一个随机的对称密钥,用证书的公钥加密。客户端
将公钥加密后的密钥发送到服务器
。服务器
接收到客户端
发来的密文密钥之后,用自己之前保留的私钥对其进行非对称解密,解密之后就得到客户端的密钥,然后用客户端密钥对返回数据进行对称加密,酱紫传输的数据都是密文啦。服务器
将加密后的密文返回到客户端
。客户端
收到后,用自己的密钥对其进行对称解密,得到服务器
返回的数据。思路: 这道题考查的知识点,不仅仅是数字签名,数字证书,很可能面试官也会问你https的原理的,因为https原理跟数字证书有关的哈,大家需要掌握https原理哦。
数字证书是指在互联网通讯中标志通讯各方身份信息的一个数字认证,人们可以在网上用它来识别对方的身份。它的出现,是为了避免身份被篡改冒充的。比如Https的数字证书,就是为了避免公钥被中间人冒充篡改:
公钥和个人等信息,经过Hash摘要算法加密,形成消息摘要
;将消息摘要拿到拥有公信力的认证中心(CA),用它的私钥对消息摘要加密,形成数字签名。
公钥和个人信息、数字签名共同构成数字证书。
思路: 这道题考察的知识点是DNS域名解析
,http请求的过程,是涉及到DNS域名解析的,这道面试题也挺经典的,大家可以看下《图解HTTP》那本书哈。
DNS,英文全称是
domain name system
,域名解析系统,是Internet上作为域名和IP相互映射的一个分布式数据库。它的作用很明确,就是可以根据域名查出对应的IP地址。在浏览器缓存、本地DNS服务器、根域名服务器都是怎么查找的,大家回答的时候都可以说下哈。
www.baidu.com
的IP地址:www.baidu.com
对应的IP地址,找到就直接返回;否则进行下一步。.com
的顶级域名服务器的IP地址的列表。.com
的顶级域名服务器发送一个请求,返回负责.baidu
的权威域名服务器的IP地址列表。www.baidu.com
所对应的IP地址。思路: 这是一个比较基础的知识点,经常有小伙伴会搞混。
具体来说,Socket是一套标准,它完成了对TCP/IP的高度封装,屏蔽网络细节,以方便开发者更好地进行网络编程。
WebSocket是一个持久化的协议,它是伴随H5而出的协议,用来解决http不支持持久化连接的问题。
Socket一个是网编编程的标准接口,而WebSocket则是应用层通信协议。
Socket其实就是等于:IP地址 + 端口 + 协议。
思路: 这道题有点偏Java web方向的。以前记得刚出来实习找工作的时候,面试官可喜欢问这道题啦,当时我记的答案就是,forward是转发,redirect是重定向。
我的答案如下:
直接转发方式(Forward) ,客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
间接转发方式(Redirect): 实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。
Cookie
是保存在客户端的一小块文本串的数据。客户端向服务器发起请求时,服务端会向客户端发送一个Cookie
,客户端就把Cookie
保存起来。在客户端下次向同一服务器再发起请求时,Cookie
被携带发送到服务器。服务器就是根据这个Cookie
来确认身份的。
session
指的就是服务器和客户端一次会话的过程。Session
利用Cookie进行信息处理的,当用户首先进行了请求后,服务端就在用户浏览器上创建了一个Cookie,当这个Session
结束时,其实就是意味着这个Cookie就过期了。Session对象存储着特定用户会话所需的属性及配置信息。
来看个图吧:
用户第一次请求服务器时,服务器
根据用户提交的信息,创建对应的Session
,请求返回时将此Session的唯一标识信息SessionID
返回给浏览器,浏览器接收到服务器返回的SessionID
信息后,会将此信息存入Cookie
中,同时Cookie记录此SessionID
是属于哪个域名。
当用户第二次访问服务器时,请求会自动判断此域名下是否存在Cookie
信息,如果存在,则自动将Cookie信息也发送给服务端,服务端会从Cookie
中获取SessionID
,再根据 SessionID
查找对应的Session
信息,如果没有找到,说明用户没有登录或者登录失效,如果找到Session
证明用户已经登录可执行后面操作。
一般可以这么认为:
网络号
+ 主机号
。
IP地址分为A,B,C,D,E五大类:
子网掩码的表示方式为:详解IP地址后面斜杠加具体数字
如:xx.xx.xx.2/25
xx.xx.xx.0/25
通俗一点就是,斜杠后面的数字就表示子网掩码,数字具体代表32位子网掩码(二进制形式)中前面的“1”的个数。
而且前面的“ip地址”也不一定是一个ip地址,也可能是一个网络号(末位是0)。
通过后面数字可以将前面的网段进一步细划分成具体的子网。
所以
xx.xx.xx.2/24 ——>表示一个ip地址xx.xx.xx.2,25告诉了这个ip地址所对应的子网掩码。
xx.xx.xx.0/24 ——>表示一个网段,并且25告诉了当前具体的子网掩码。
Class A
.Class B.
Class C
.Binary Classifications of the three classes are,
network part
is 8 bits)network part
is 16 bits)network part
is 24 bits)For example let us consider an IP address 192.35.128.93
which belongs to the network with 6 subnets
. How to calculate subnet mask?
Step 1: Determine the network class of the given IP Address 192.35.128.93
.
Step 2: As the IP starts with 192, the address falls on Class C.
Step 3: Calculate Number of bits, to define the subnets.
Step 4: Formula to calculate Number of bits = log 2 ( N u m b e r _ o f _ s u b n e t s + 2 ) \log_2 (Number\_of\_subnets + 2) log2(Number_of_subnets+2)
Step 5: Given here is 6 subnets
, Applying the values in the formula, we get, Number of Bits =:
log 2 ( N u m b e r _ o f _ s u b n e t s + 2 ) = log 2 ( 6 + 2 ) = 3 b i t s . \log_2(Number\_of\_subnets + 2) =\log_2(6+2) = 3 bits. log2(Number_of_subnets+2)=log2(6+2)=3bits.
Step 6: Use the bits calculated in the above step, to compose the subnet mask in binary form using the default binary classification.
Step 7: IP Address 192.35.128.93
falls on Class C
, whose Binary Classification is :
Step 8: Convert the binary values to its equivalent decimal values using the following rules:
n
is either 1 or 0 in the corresponding position in the octet sequence.Step 9: Converting the IP 11111111.11111111.11111111.11100000 into binary using the above rules, we get,
11111111 = 255
11111111 = 255
11111111 = 255
11100000 = (128 x 1) + (64 x 1) + (32 x 1) + (16 x 0) + (8 x 0) + (4 x 0) + (2 x 0) + (1 x 0) = 224
Step 10: Hence, the IP Subnet Mask = 255.255.255.224
基于TCP的应用层协议有:HTTP、FTP、SMTP、TELNET、SSH
协议名 | 名称 | 端口 |
---|---|---|
HTTP | HyperText Transfer Protocol (超文本传输协议) |
默认端口80 |
FTP: | File Transfer Protocol (文件传输协议), |
ftp端口号20和21的区别就是一个是数据端口,一个是控制端口,数据端口不一定是20,而控制端口一般是21 |
SMTP | Simple Mail Transfer Protocol (简单邮件传输协议) |
默认端口25 |
TELNET | Teletype over the Network (网络电传) |
默认端口23 |
SSH | Secure Shell (安全外壳协议) |
默认端口 22 |
基于UDP的应用层协议:DNS、TFTP、SNMP
协议名 | 名称 | 端口 |
---|---|---|
DNS | Domain Name Service (域名服务) | 默认端口 53 |
TFTP | Trivial File Transfer Protocol (简单文件传输协议) | 默认端口69 |
SNMP | Simple Network Management Protocol(简单网络管理协议) | 通过UDP端口161接收,只有Trap信息采用UDP端口162 |
ICMP,Internet Control Message Protocol
,Internet控制消息协议。
ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。
它是一个非常重要的协议,它对于网络安全具有极其重要的意义。它属于网络层
协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。
当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。
比如我们日常使用得比较多的ping
,就是基于ICMP的。
思路: TCP连接的三次握手机制,最重要的知识点,必须得会,通讯过程以及客户端、服务器的对应的状态都需要记住哈。
TCp提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的就是同步连接双方的序列号和确认号并交换TCP窗口大小信息。我们一起来看下流程图哈:
客户端
就进入SYN_SEND
状态服务器端
就进入SYN_RCV
状态。客户端
进入ESTABLISHED
状态,当服务器端
接收到这个包时,也进入ESTABLISHED
状态。思路: TCP握手为什么不能是两次,为什么不能是四次呢?为了方便理解,我们以男孩子和女孩子谈恋爱为例子:两个人能走到一起,最重要的事情就是相爱,就是我爱你,并且我知道,你也爱我,接下来我们以此来模拟三次握手的过程:
如果只有两次握手,女孩子可能就不知道,她的那句我也爱你
,男孩子是否收到,恋爱关系就不能愉快展开。
因为握手不能是四次呢?因为三次已经够了,三次已经能让双方都知道:你爱我,我也爱你。而四次就多余了。
思路: TCP的四次挥手,也是最重要的知识点,一般跟三次握手会一起考的,必须得记住。
客户端
进入FIN_WAIT_1
状态。服务器端
进入CLOSE_WAIT
状态,客户端
接收到这个确认包之后,进入FIN_WAIT_2
状态。服务器端
进入LAST_ACK
状态,等待来自客户端
的最后一个ACK。客户端
接收到来自服务器端
的关闭请求,发送一个确认包,并进入TIME_WAIT
状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的ACK ,认为服务器端
已经正常关闭连接,于是自己也关闭连接,进入CLOSED状态。服务器端
接收到这个确认包之后,关闭连接,进入CLOSED
状态。思路: TCP挥手为什么需要四次呢?为了方便大家理解,再举个生活的例子吧。
小明和小红打电话聊天,通话差不多要结束时,小红说,“我没啥要说的了”。小明回答,“我知道了”。但是小明可能还有要说的话,小红不能要求小明跟着她自己的节奏结束通话,于是小明可能又叽叽歪歪说了一通,最后小明说,“我说完了”,小红回答,“我知道了”,这样通话才算结束。
四次挥手是TCP连接的正常断开过程,它是为了确保数据的可靠传输而设计的。每个端口都需要发送一个FIN和收到一个ACK来关闭连接,因此需要四次握手来确保双方都知道连接已经关闭。
在TCP连接中,如果一方只发送一个FIN来关闭连接,那么另一方可能不知道连接已经关闭,因为它仍然可以发送数据。这将导致连接的状态不一致,可能会在另一方发送数据时造成问题。
因此,四次挥手确保了连接的可靠关闭,防止了任何数据的遗漏和重复。虽然少于四次的挥手可能在某些情况下可以工作,但它不是TCP协议规定的标准方法,不建议使用。
实际上,四次握手是一对两次握手的过程。虽然在某些情况下,第二次和第三次握手可以设置在同一个数据包中,但这并不是完全正确的。
四次握手可以被理解为一对两次握手。第一阶段是,当客户端向服务器发送FIN标志时,服务器会回应一个ACK标志作为确认。这可以通过以下语句来理解:
客户端 ------FIN-----> 服务器
客户端 <-----ACK------ 服务器
此时,客户端处于等待状态,等待来自服务器的FIN标志,以便关闭连接。这个状态可以称为FIN_WAIT_2。
由于TCP连接是全双工模式的,因此如果连接的一侧已经中断,那么该侧就不能再发送数据了,但是仍然可以从另一侧接收数据。在这种情况下,当客户端处于FIN_WAIT_2状态时,服务器可以继续发送数据。一旦服务器完成数据发送,就会向客户端发送FIN标志作为终止请求,然后客户端发送ACK标志作为确认终止连接。这可以通过以下语句来看到:
客户端 <-----FIN------ 服务器
客户端 ------ACK-----> 服务器
正如上面解释的那样,在这种情况下,第二步和第三步不能作为一个数据包发送,因为它们属于两个不同的状态。
四次握手在这种情况下是必要的,因为客户端发送的第一个FIN标志是终止请求,而收到的第一个ACK标志仅仅是对FIN1的响应。此时仅仅是客户端的连接被断开了,但服务器仍然在工作状态。这意味着它可能仍有一些数据要发送。因此,在这种情况下不能突然中断连接,还需要由服务器执行另外两步操作。
另一个原因是双方难以确定对方为什么没有响应。而且,不仅离线状态会导致数据包丢失,服务器处理过程中的其他异常也可能导致数据包丢失。在这种情况下,另一个问题是客户端必须等待很长时间,直到超时。因此,四次握手看起来是解决这些问题的更好和更简单的选项。
TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS。
TCP三次握手,发送端和接收端进入到ESTABLISHED
状态,它们即可以愉快地传输数据啦。
但是发送端不能疯狂地向接收端发送数据,因为接收端接收不过来的话,接收方只能把处理不过来的数据存在缓存区里。如果缓存区都满了,发送方还在疯狂发送数据的话,接收方只能把收到的数据包丢掉,这就浪费了网络资源啦。
TCP 提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是流量控制。
TCP通过滑动窗口来控制流量,我们看下流量控制的简要流程吧:
首先双方三次握手,初始化各自的窗口大小,均为 400 个字节。
假如当前发送方给接收方发送了200个字节,那么,发送方的SND.NXT会右移200个字节,也就是说当前的可用窗口减少了200 个字节。
接受方收到后,放到缓冲队列里面,REV.WND =400-200=200字节,所以win=200字节返回给发送方。接收方会在 ACK 的报文首部带上缩小后的滑动窗口200字节
发送方又发送200字节过来,200字节到达,继续放到缓冲队列。不过这时候,由于大量负载的原因,接受方处理不了这么多字节,只能处理100字节,剩余的100字节继续放到缓冲队列。这时候,REV.WND = 400-200-100=100字节,即win=100返回发送方。
发送方继续干活,发送100字节过来,这时候,接受窗口win变为0。
发送方停止发送,开启一个定时任务,每隔一段时间,就去询问接受方,直到win大于0,才继续开始发送。
思路讲解: TCP滑动窗口是个高频考点,我们需要知道TCP报文首部有个字段win控制窗口大小的,同时也需要掌握,滑动窗口是怎么滑的。
这就好像我们面对面在聊天,你说完一句,我应答之后,你才能说下一句。那么,如果我在忙其他事情,没有能够及时回复你呢?你说完一句后,要等到我忙完回复你,你才说下句,这显然不现实,效率太低。
为了解决这个问题,TCP引入了窗口,它是操作系统开辟的一个缓存空间。窗口大小值表示无需等待确认应答,而可以继续发送数据的最大值。
TCP头部有个字段叫win,也即那个16位的窗口大小,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。
TCP 发送一个数据,如果需要收到确认应答,才会发送下一个数据。这样的话就会有个缺点:效率会比较低。
通俗点讲,就是接受方每次收到数据包,在发送确认报文的时候,同时告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,我们就称之为接受窗口大小。这就是win。
TCP 滑动窗口分为两种: 发送窗口和接收窗口。发送端的滑动窗口包含四大部分,如下:
已发送且已收到ACK确认
已发送但未收到ACK确认
未发送但可以发送
未发送也不可以发送
虚线矩形框,就是发送窗口。
SND.WND: 表示发送窗口的大小,上图虚线框的格子数是14个,即发送窗口大小是14。
SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。
SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。
接收方的滑动窗口包含三大部分,如下:
已成功接收并确认
未收到数据但可以接收
未收到数据并不可以接收的数据
虚线矩形框,就是接收窗口。
REV.WND: 表示接收窗口的大小,上图虚线框的格子就是9个。
REV.NXT:下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。
思路: 这道题,校招的时候,问的概率高点,概念性的东西,TCP是面向连接,而UDP是无连接。
如果发送方疯狂地向接收方发送很小的数据包,比如一次就发送1个字节,那么显然会有问题。
TCP/IP协议中,无论发送多少数据,总是需要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。
Nagle算法:任意时刻,最多只能有一个未被确认的小段。所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。
Nagle算法的实现规则:
如果包长度达到MSS,则允许发送;
如果该包含有FIN,则允许发送;
设置了TCP_NODELAY选项,则允许发送;
未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
上述条件都未满足,但发生了超时(一般为200ms),则立即发送。
如果接受方刚接收到发送方的数据包,在很短很短的时间内,又接收到第二个包。那么请问接收方是一个一个地回复好点,还是合在一起回复好呢?
接收方收到数据包后,如果暂时没有数据要发给对端,它可以等一小段时间,再确认(Linux上默认是40ms)。如果这段时间刚好有数据要传给对端,ACK就随着数据传输,而不需要单独发送一次ACK。如果超过时间还没有数据要发送,也发送ACK,避免对端以为丢包。
但是有些场景不能用延迟确认,比如发现了乱序包、接收到了大于一个 frame 的报文,且需要调整窗口大小等。
一般情况下,Nagle算法和延迟确认不能一起使用,Nagle算法意味着延迟发,延迟确认意味着延迟接收,酱紫就会造成更大的延迟,会产生性能问题。
RPC,可以基于TCP协议,也可以基于HTTP协议
HTTP,基于HTTP协议
RPC,使⽤⾃定义的TCP协议,可以让请求报⽂体积更⼩,或者使⽤HTTP2协议,也可以很好的减少报⽂的体积,提⾼传输效率
HTTP,如果是基于HTTP1.1的协议,请求中会包含很多⽆⽤的内容,如果是基于HTTP2.0,那么简单的封装以下是可以作为⼀个RPC来使⽤的,这时标准RPC框架更多的是服务治理
主要在于序列化和反序列化的耗时
RPC,可以基于thrift
实现⾼效的⼆进制传输
HTTP,⼤部分是通过json
来实现的,字节⼤⼩和序列化耗时都⽐thrift要更消耗性能
RPC,基本都⾃带了负载均衡策略
HTTP,需要配置Nginx,HAProxy来实现
RPC,能做到⾃动通知,不影响上游
HTTP,需要事先通知,修改Nginx/HAProxy配置
RPC主要⽤于公司内部的服务调⽤,性能消耗低,传输效率⾼,服务治理⽅便。HTTP主要⽤于对外的异构环境,浏览器接⼝调⽤,APP接⼝调⽤,第三⽅接⼝调⽤等。
Ref: