计算机网络是计算机科学与技术专业的必修课,也是移动端,前端,后端都会涉及并用到的知识点,可想而知它的重要性。因此它也成为了iOS面试中常常被问及的问题。准备面试的话,网络相关的知识点必定不能错过。这里总结了一些我认为有用的和最近面试遇到的网络相关知识点。html
去年写过一篇《图解TCP/IP》总结的文章,也能够对着看下。前端
网络有两种分层模型,一种是ISO(国际标准化组织)制定的OSI(Open System Interconnect)模型,它将网络分为七层。一种是TCP/IP的四层网络模型。OSI是一种学术上的国际标准,理想概念,TCP/IP是事实上的国际标准,被普遍应用于现实生活中。二者的关系能够看这个图:web
注:也有说五层模型的,它跟四层模型的区别就是,在OSI模型中的数据链路层和物理层,前者将其做为两层,后者将其合并为一层称为网络接口层。通常做为面试题的话都是须要讲出OSI七层模型的。面试
各个分层的含义以及它们之间的关系用这张图表示:算法
GET:请求获取Request-URI标识的资源,请求参数附加在url上,明文展现。数据库
POST:在Request-URI所标识的资源后附加新的数据,经常使用于修改服务器资源或者提交资源到服务器。POST请求体是放到body中的,能够指定编码方式,更加安全。小程序
HEAD:请求获取由Request-URI所标识的资源的响应消息报头。后端
PUT:请求服务器存储一个资源,并用Request-URI做为其标识。浏览器
DELETE:请求服务器删除Request-URI所标识的资源。缓存
TRACE:请求服务器回送收到的请求信息,主要用于测试或诊断。
OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求。
以该连接为例:zhangferry.com/2019/08/31/…
在Chrome查看其请求的Headers信息。
General
这里标记了请求的URL,请求方法为GET。状态码为304,表明文件未修改,能够直接使用缓存的文件。远程地址为185.199.111.153:443,此IP为Github 服务器地址,是由于个人博客是部署在GitHub上的。
除了304还有别的状态码,分别是:
200 OK
客户端请求成功301 Moved Permanently
请求永久重定向302 Moved Temporarily
请求临时重定向304 Not Modified
文件未修改,能够直接使用缓存的文件。400 Bad Request
因为客户端请求有语法错误,不能被服务器所理解。401 Unauthorized
请求未经受权。这个状态代码必须和WWW-Authenticate报头域一块儿使用403 Forbidden
服务器收到请求,可是拒绝提供服务。服务器一般会在响应正文中给出不提供服务的缘由404 Not Found
请求的资源不存在,例如,输入了错误的URL500 Internal Server Error
服务器发生不可预期的错误,致使没法完成客户端的请求。503 Service Unavailable
服务器当前不可以处理客户端的请求,在一段时间以后,服务器可能会恢复正常。Response Headers:
content-encoding:用于指定压缩算法
content-length:资源的大小,以十进制字节数表示。
content-type:指示资源的媒体类型。图中所示内容类型为html的文本类型,文字编码方式为utf-8
last-modified:上次内容修改的日期,为6月8号
status:304 文件未修改状态码
注:其中content-type在响应头中表明,须要解析的格式。在请求头中表明上传到服务器的内容格式。
Request Headers:
:method:GET请求
:path:url路径
:scheme:https请求
accept:通知服务器能够返回的数据类型。
accept-encoding:编码算法,一般是压缩算法,可用于发送回的资源
accept-language:通知服务器预期发送回的语言类型。这是一个提示,并不必定由用户彻底控制:服务器应该始终注意不要覆盖用户的显式选择(好比从下拉列表中选择语言)。
cookie:浏览器cookie
user-agent:用户代理,标记系统和浏览器内核
更多请求头的字段含义能够参考这里:HTTP headers
在了解TCP握手以前咱们先看下TCP的报文样式:
其中控制位(Control Flag)标记着握手阶段的各个状态。
示意图以下:
三次握手是指创建一个TCP链接时,须要客户端和服务器总共发送3个数据包。
一、第一次握手(SYN=1, seq=x)
客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算链接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SEND
状态。
二、第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1)
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择本身 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD
状态。
三、第三次握手(ACK=1, ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,而且把服务器发来 ACK 的序号字段+1,放在肯定字段中发送给对方,而且在数据段放写ISN的+1
发送完毕后,客户端进入 ESTABLISHED
状态,当服务器端接收到这个包时,也进入 ESTABLISHED
状态,TCP 握手结束。
问题一:为何须要三次握手呢?
在谢希仁著的《计算机网络》里说,『为了防止已失效的链接请求报文段忽然又传送到了服务端,于是产生错误』。怎么理解呢,咱们假设一种状况,有一个创建链接的第一次握手的报文段由于滞留到网络中过了较长时间才发送到服务端。这时服务器是要作ACK应答的,若是只有两次握手就表明链接创建,那服务器此时就要等待客户端发送创建链接以后的数据。而这只是一个因滞留而废弃的请求,是否是白白浪费了不少服务器资源。
从另外一个角度看这个问题,TCP是全双工的通讯模式,须要保证两端都已经创建可靠有效的链接。在三次握手过程当中,咱们能够确认的状态是:
第一次握手:服务器确认本身接收OK,服务端确认客户端发送OK。
第二次握手:客户端确认本身发送OK,客户端确认本身接收OK,客户端确认服务器发送OK,客户端确认服务器接收OK。
第三次握手:服务器确认本身发送OK,服务器确认客户端接收OK。
只有握手三次才能达到全双工的目的:确认本身和对方都可以接收和发送消息。
示意图以下:
四次挥手表示要发送四个包,挥手的目的是断开链接。
一、第一次挥手(FIN=1, seq=x)
假设客户端想要关闭链接,客户端发送一个 FIN 标志位置为1的包,表示本身已经没有数据能够发送了,可是仍然能够接受数据。
发送完毕后,客户端进入 FIN_WAIT_1
状态。
二、第二次挥手(ACK=1,ACKnum=x+1)
服务器端确认客户端的 FIN 包,发送一个确认包,代表本身接受到了客户端关闭链接的请求,但尚未准备好关闭链接。
发送完毕后,服务器端进入 CLOSE_WAIT
状态,客户端接收到这个确认包以后,进入 FIN_WAIT_2
状态,等待服务器端关闭链接。
三、第三次挥手(FIN=1,seq=y)
服务器端准备好关闭链接时,向客户端发送结束链接请求,FIN 置为1。
发送完毕后,服务器端进入 LAST_ACK
状态,等待来自客户端的最后一个ACK。
四、第四次挥手(ACK=1,ACKnum=y+1)
客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT
状态,等待可能出现的要求重传的 ACK 包。
服务器端接收到这个确认包以后,关闭链接,进入 CLOSED
状态。
客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)以后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭链接,因而本身也关闭链接,进入 CLOSED
状态。
问题一:为何挥手须要四次呢?为何不能将ACK和FIN报文一块儿发送?
当服务器收到FIN报文时,极可能并不会当即关闭SOCKET,因此只能先回复一个ACK报文,告诉客户端『你发的FIN我收到了』。只有等到服务端全部的报文都发送完了,才能发FIN报文,因此要将ACK和FIN分开发送,这就致使须要四次挥手。
问题二:为何TIMED_WAIT以后要等2MSL才进入CLOSED状态?
MSL是TCP报文的最大生命周期,由于TIME_WAIT持续在2MSL就能够保证在两个传输方向上的还没有接收到或者迟到的报文段已经消失,同时也是在理论上保证最后一个报文可靠到达。假设最后一个ACK丢失,那么服务器会再重发一个FIN,这是虽然客户端的进程不在了,可是TCP链接还在,仍然能够重发LAST_ACK。
HTTPS = HTTP + TLS/SSL,它使用的端口默认为443,它的创建能够用下图表示:
一、客户端首次请求服务器,告诉服务器本身支持的协议版本,支持的加密算法及压缩算法,并生成一个随机数(client random)告知服务器。
二、服务器确认双方使用的加密方法,并返回给客户端证书以及一个服务器生成的随机数(server random)
三、客户端收到证书后,首先验证证书的有效性,而后生成一个新的随机数(premaster secret),并使用数字证书中的公钥,加密这个随机数,发送给服务器。
四、服务器接收到加密后的随机数后,使用私钥进行解密,获取这个随机数(premaster secret
五、服务器和客户端根据约定的加密方法,使用前面的三个随机数(client random, server random, premaster secret),生成『对话密钥』(session key),用来加密接下来的整个对话过程(对称加密)。
有一篇由浅入深介绍HTTPS的文章能够阅读一下:看图学HTTPS
问题一:为何握手过程须要三个随机数,并且安全性只取决于第三个随机数?
前两个随机数是明文传输,存在被拦截的风险,第三个随机数是经过证书公钥加密的,只有它是通过加密的,因此它保证了整个流程的安全性。前两个随机数的目的是为了保证最终对话密钥的『更加随机性』。
问题二:Charles如何实现HTTPS的拦截?
Charles要实现对https的拦截,须要在客户端安装Charles的证书并信任它,而后Charles扮演中间人,在客户端面前充当服务器,在服务器面前充当客户端。
问题三:为何有些HTTPS请求(例如微信)抓包结果还是加密的,如何实现的?
我在聊天过程当中并无抓到会话的请求,在小程序启动的时候到是抓到了一个加密内容。我手动触发该连接会下载一个加密文件,我猜想这种加密是内容层面的加密,它的解密是由客户端完成的,而不是在HTTPS创建过程完成的。
另外在研究这个问题的过程当中,又发现了一些有趣的问题:
一、图中所示的三个https请求分别对应三个不一样类型的图标,它们分别表明什么意思呢?
二、第三个请求https://mtalk.google.com:5228
图标和请求内容都加了锁,这个加锁是在https之上又加了一层锁吗?
这些问题暂时没有确切的答案,但愿了解的小伙伴告知一下哈。
DNS(Domain name system)域名系统。DNS是因特网上做为域名和IP地址相互映射的一个分布式数据库,可以使用户经过域名访问到对应的服务器(IP地址)。具体的解析流程是这样的:
一、浏览器中输入想要访问的网站域名,操做系统会检查本地hosts文件是否有这个网址的映射关系,若是有就调用这个IP地址映射,完成域名解析。没有的话就走第二步。
二、客户端回向本地DNS服务器发起查询,若是本地DNS服务器收到请求,并能够在本地配置区域资源中查到该域名,就将对应结果返回为给客户端。若是没有就走第三步。
三、根据本地DNS服务器的设置,采用递归或者迭代查询,直至解析完成。
其中递归查询和迭代查询能够用以下两图表示。
如图所示,递归查询是由DNS服务器一级一级查询传递的。
若是所示,迭代查询是找到指定DNS服务器,由客户端发起查询。
DNS劫持发生在DNS服务器上,当客户端请求解析域名时将其导向错误的服务器(IP)地址。
常见的解决办法是使用本身的解析服务器或者是将域名以IP地址的方式发出去以绕过DNS解析。
HTTP 是无状态协议,说明它不能以状态来区分和管理请求和响应。也就是说,服务器单从网络链接上无从知道客户身份。
但是怎么办呢?就给客户端们颁发一个通行证吧,每人一个,不管谁访问都必须携带本身通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工做原理。
Cookie:Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,实际上Cookie是服务器在本地机器上存储的一小段文本,并随着每次请求发送到服务器。Cookie技术经过请求和响应报文中写入Cookie信息来控制客户端的状态。
Session:Session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构来保存信息。当有用户请求建立一个session时,服务器会先检查这个客户端里是否已经包含了一个Session标识(session id),若是有就经过session id把session检索出来。若是没有就建立一个对应此Session的session id。这个session id会在本次响应中返回给客户端。
二者有如下区别:
一、存储位置:Cookie存放在客户端上,Session数据存放在服务器上。
二、Session 的运行依赖 session id,而 session id 是存在 Cookie 中的,也就是说,若是浏览器禁用了 Cookie ,同时 Session 也会失效
三、安全性:Cookie存在浏览器中,可能会被一些程序复制,篡改;而Session存在服务器相对安全不少。
四、性能:Session会在必定时间内保存在服务器上,当访问增多,会对服务器形成必定的压力。考虑到减轻服务器压力,应当使用Cookie
CDN(Content Delivery Network),根本做用是将网站的内容发布到最接近用户的网络『边缘』,以提升用户访问速度。归纳的来讲:CDN = 镜像(Mirror) + 缓存(Cache) + 总体负载均衡(GSLB)。
目前CDN都以缓存网站中的静态数据为主,如CSS、JS、图片和静态网页等数据。用户在从主站服务器请求到动态内容后再从CDN上下载这些静态数据,从而加速网页数据内容的下载速度,如淘宝有90%以上的数据都是由CDN来提供的。
一个用户访问某个静态文件(如CSS),这个静态文件的域名假如是www.baidu.com,而这个域名最终会被指向CDN全局中CDN负载均衡服务器,再由这个负载均衡服务器来最终分配是哪一个地方的访问用户,返回给离这个访问用户最近的CDN节点。以后用户就直接去这个CDN节点访问这个静态文件了,若是这个节点中请求的文件不存在,就会再回到源站去获取这个文件,而后再返回给用户。
socket位于应用层和传输层之间:
它的做用是为了应用层可以更方便的将数据经由传输层来传输。因此它的本质就是对TCP/IP的封装,而后应用程序直接调用socket API便可进行通讯。上文中说的三次握手和四次挥手便是经过socket完成的。
咱们能够从iOS中网络库分层找到BSD Sockets
,它是位于CFNetwork
之下。在CFNetwork
中还有一个CFSocket
,推测是对BSD Sockets
的封装。
WebRTC是一个能够用在视频聊天,音频聊天或P2P文件分享等Web App中的 API。借助WebRTC,你能够在基于开放标准的应用程序中添加实时通讯功能。它支持在同级之间发送视频,语音和通用数据,从而使开发人员可以构建功能强大的语音和视频通讯解决方案。该技术可在全部现代浏览器以及全部主要平台的本机客户端上使用。WebRTC项目是开源的,并获得Apple,Google,Microsoft和Mozilla等的支持。
这个是某公司二面时的问题,是一个开放性问题,我总结了如下几点可能:
一、该时刻请求量过大
二、该地的网络节点较不稳定
三、用户行为习惯,好比该时刻为上班高峰期,或者某个群体的特定习惯
若是有对网络方面比较熟悉的小伙伴也能够补充。