持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
1. 前言: 作为一个有自我修养的iOS工程师, 对网络的理解体现在开发中的方方面面
- 如果你是个科班毕业的iOS开发者, 对计算机网络的基础认识可能是通过<<计算机网络>>这本教材.
- 如果你是个其他专业转向iOS的开发者, 对计算机网络的认识可能来自于这本无数大佬安利的<<图解HTTP>>
- 下面就由我们来结合iOS开发日常工作中的方方面, 来一起对iOS中常用的网络相关知识做一个不成体系的梳理, 抛砖引玉, 如在阅读过程中发现错误, 请及时在评论区交流指正:)
2. iOS开发中的网络相关基操Tips
2.1 HTTP的请求方式有哪些?
- GET、POST、PUT、DELETE、HEAD、OPTIONS
- 其实我们在开发过程中用的最多的请求方式的是GET和POST, 对其他的⽅式使⽤的很少, 在有些公司采⽤restful⻛格的时候会⽤PUT来做更新, DELETE做删除.
2.1.1 GET和POST的区别
- 从用法来说, GET主要是用来获取资源的, 语义上具有安全性、幂等性、可缓存性;
- 从用法来说, POST主要是用来修改资源的, 语义上具有不安全性、非幂等性、不可缓存性;
-
- 安全性, 指的是是否能引起server端的变化.
-
- 幂等性, 指的是单次请求和多次请求的结果是否一致.
-
- 可缓存性, 指的是请求是否可以被缓存.
2.2 关于HTTP的持久连接的理解
- 随着我们要处理的资源越来越多, 如果还是采⽤非持久连接的⽅式就会很浪费资源, 因为会牵扯到⼤量的连接的建⽴和销毁.
- 所以为了解决这种问题, 提出了持久连接来改进.
- 就是在连接建⽴以后, 处理完任务不是⽴即销毁, ⽽是有⼀个等待时间, 在这段时间范围内可以对同⼀服务的请求进⾏复⽤, 减少连接的创建和销毁次数.
2.3 怎样判断一个HTTP请求是否已经完成了?
- 判断⼀个请求是否完成的⽅式有两种.
- 第⼀种: 通过响应报⽂中的
content-length
字段来判断接收的数据是否已经接收完毕了, 如果接收完 毕了就表示本次请求完成了. - 第⼆种: 在POST请求中会存在多次响应, 在最后⼀次响应的报⽂中会包含⼀个空的
chunck
, 我们可以以此来判断请求是否完成了.
2.4 HTTP连接过程中的三次握手和四次挥手
2.4.1 三次握手
- 发送⼀个http请求要先建⽴连接.
- ⾸先server端要监听端⼝, 此时server端处于LISTEN状态.
- client端发送⼀个SYN同步包到server端, 并将⾃⼰(client端)的状态置为SYN_SENT
- server端收到client的syn, 会回传⼀个ACK确认信息, 以及⼀个SYN同步包, 同意建⽴连接, 将server 端状态置为SYN_RCVD.
- client端收到服务端的SYN包后, 发送⼀个ACK给server端. 并将⾃⼰的状态改为ESTABLISHED.
- server端接收到ACK信息后, 会将状态改为ESTABLISHED.
- 这样就完成了三次握⼿, 就可以进⾏数据的传递了.
2.4.2 四次挥手
- 关于断开连接的四次挥⼿的流程, 主要是因为全双工通道的机制.
- client端发送⼀个FIN信号给server端, 并进⼊FIN_WAIT_1状态.
- server端接收到消息后会返回⼀个ACK确认, 并进⼊CLOSE_WAIT状态.
- client端接收到ACK确认信息后, 将状态改为FIN_WAIT_2. 此时已经完成了半关闭状态.
- 当server端要传输的数据也完成以后, 就会发送⼀个FIN信号给client端, 并将状态置为LAST_ACK.
- client端接收到FIN信号后会返回⼀个ACK给server端, 并将状态置为TIME_WAIT.
- server端在收到ACK确认信息后, 会进⼊CLOSE状态.
- client端会在等待2MSL(报⽂最⼤⽣存时间)的时间后进⼊CLOSE状态.
2.4.3 为什么要等待2MSL?
- 为了保证可靠关闭.
- 如果server没有收到最后⼀个ACK, 那么就会重发FIN.
- 为了避免端⼝重⽤带来的数据混淆, 如果client直接进⼊CLOSE状态, ⼜⽤相同的端⼝建⽴⼀个连接, 上⼀次连接的部分数据在⽹络中延迟到达server, 数据就有可能发⽣混淆.
2.5 TCP和UDP的区别
- TCP是传输控制协议, 它的特点是: ⾯向连接的、可靠的、⾯向字节流的, 流量控制、拥塞控制.
- UDP是⽤户数据报协议, 它的特点是: ⽆连接、尽最⼤可能交付、⾯向报⽂的, 不保证数据的完整 性.
2.5.1 TCP是怎样保证传输过程的可靠性的?
- TCP在保证传输的可靠性⽅⾯主要有以下机制
- 校验和: 发送⽅在发送数据之前计算校验和, 接收⽅收到数据后同样计算, 如果不⼀致, 那么传输有 误.
- 确认应答: TCP进⾏传输时数据都进⾏编号, 每次接收⽅返回ACK都有确认序列号.
- 超时重传: 如果发送⽅发送数据⼀段时间后没有收到ACK, 那么就重发数据.
- 对于超时重传的情况有两种
-
- ⼀种是客户端发送到服务端的数据超时了, 那么服务端可能会收到两份数据, 服务端会丢弃重复的数据.
-
- 还有⼀种是服务端确认信息超时了, 那么客户端在收到确认信息的时候什么都不做.
2.5.2 TCP的流量控制与拥塞控制
- TCP的流量控制是通过滑动窗⼝协议来实现的. TCP协议报⽂头包含16位的窗⼝⼤⼩, 接收⽅在返回ACK时会把⾃⼰的即时窗⼝填⼊, 发送⽅就根据报⽂中窗⼝的⼤⼩来控制发送的速度.
- 拥塞控制是为了解决⽹络中涌⼊⼤量数据包的⼀种机制.
- 这⾥主要使⽤慢开始, 拥塞避免和快恢复, 快重传两种策略.
-
- 慢开始是指刚开始发送数据的时候, 拥塞窗⼝是1, 以后每次收到ACK后, 将拥塞窗⼝的值按照指数级增⻓, 当增⻓达到了拥塞窗⼝的⻔限值的时候, 就会以线性⽅式增⻓, 来控制发送数据的速度.
-
- 当发送⽹络拥塞的时候, 就会将拥塞窗⼝值改为1, 重新开始慢开始的流程. 同时将拥塞窗⼝的⻔限值改为拥塞时的⼀半.
-
- 快恢复快重传是基于慢开始的, 在发⽣⽹络拥塞的时候, 是把拥塞窗⼝的⼤⼩调到拥塞值的⼀半, 然后以线性⽅式增⻓.
2.6 DNS域名解析相关
- DNS是做域名解析的, 我们在通过域名访问服务器的时候, ⾸先会通过DNS进⾏域名解析, 得到服务器的IP地址, 然后再进⾏访问.
- 域名解析使⽤的UDP的⽅式进⾏明⽂传输的. 采⽤udp是因为它的速度更快.
- 但是因为传输的明⽂, 所以容易遭到劫持.
- 所以在解决DNS劫持的时候主要有两种⽅式, ⼀种是httpDNS, ⼀种是⻓连接.
-
- httpDNS是指通过发送⼀个http请求来解析域名. 因为普通的DNS劫持是基于UDP的, 所以我们通过 httpDNS是采⽤TCP的⽅式, 可以防⽌.
-
- ⻓连接的⽅式是指我们建⽴⼀个⻓连接服务器, 让client与中间服务器建⽴⻓连接, 并将⻓连接与域名解析服务器通过内⽹专线的⽅式进⾏连接, 以此来避免DNS的劫持.
2.7 如何保证Cookie的安全
- 对cookie内容进⾏加密处理, 这种⽅式的缺点是不能避免脚本攻击.
- 在https下传输cookie, 这也是我们使⽤最多的⽅式.
- 设置cookie为httpOnly来防⽌跨站脚本攻击.
2.8 关于HTTPS
- HTTPS是在HTTP的基础上增加了安全模块(TLS/SSL).
2.8.1 HTTPS的连接建立流程
- ⾸先client端将当前⽀持的TLS版本号, 以及⽀持的加密算法, 并⽣成⼀个随机数C⼀起发送给server端.
- server端收到消息后会选择⼀套加密算法, 并⽣成⼀个随机数S, 连同server证书返回给client端
- client端先校验server证书, 然后根据预主秘钥+C+S组装会话秘钥. 并通过server证书将预主秘钥加密发送给server端.
- server端⽤私钥进⾏解码, 得到预主秘钥后, 组装会话秘钥, 然后加密握⼿消息.
2.9 ISO模型的七层架构(应表会传网数物)
- 七层架构分别是: 应⽤层、表示层、会话层、传输层、⽹络层、数据链路层、物理层.
- 应⽤层: 最⾼层, 直接⾯对⽤户.
- 表示层: ⽤来将数据转换成另外⼀种格式, ⽐如⽂字、视频、图⽚等.
- 会话层: 负责建⽴和断开连接.
- 传输层: TCP、UDP都属于这⼀层的协议.
- ⽹络层: 定义了IP和⼦⽹掩码, ⽤来确定⽹段, 通过路由器和交换机进⾏传输. IP协议就是属于⽹络层的协议.
- 数据链路层: 把⽐特流封装成数据帧的格式.
- 物理层: 通过⽹线, 光缆等这种物理⽅式将电脑连接起来, 传递的是⽐特流.
2.10 什么是BIO/NIO/AIO?
- BIO: 同步阻塞IO, 每⼀个客户端连接, 服务端都会对应⼀个处理线程, 对于没有分配到处理线程的连 接就会被阻塞或者拒绝. 相当于⼀个连接⼀个线程.
- NIO: 同步⾮阻塞IO, 基于Reactor模型, 客户端和channel进⾏通信, channel可以进⾏读写操作. 通过多路复⽤器seletor来轮询注册在其上的channel, ⽽后再进⾏IO操作. 这样的话, 在进⾏IO操作的时候再⽤⼀个线程去处理就好. 也就是⼀个请求⼀个线程.
- AIO: 异步⾮阻塞IO, 相⽐NIO更进⼀步, 完全有操作系统来完成请求的处理, 然后通知服务端开启线 程进⾏处理, 因此是⼀个有效请求⼀个线程.
2.11 浅谈一下对HTTP的理解
- ⾸先http是超⽂本传输协议, 它是基于TCP协议的应⽤层传输协议.
- 它的特点主要有两个, ⽆连接和⽆状态
-
- 关于⽆连接是指限制每次连接只处理⼀个请求. 服务器处理完客户端的请求, 并收到客户端的应答后 就断开连接. 这是早期采⽤的⽅式, 为了追求快, 传输的资源少. 但是随着我们要处理的资源增多, 就提出了持久连接的⽅式, 来复⽤连接, 通过设置⼀个时间, 在这段时间内都可以复⽤此次连接, 只有在超过这个时间后才会断开连接.
-
- 关于⽆状态是指每次请求不会记录状态, 为了解决这种⽆状态的问题, 提出了cookie和session机制. cookie和session都是⽤来记录⽤户状态, 区分⽤户的. 主要的区别在于cookie是保存在客户端, session是存储在服务端的. session的实现也是基于cookie机制的.
- 另外我们在发送⼀个http请求的时候还主要请求报⽂和响应报⽂.
-
- 关于请求报⽂主要包含请求⾏, 在请求⾏⾥包含了请求⽅式是GET还是POST, 还有URL, 以及当前协议的版本是http1.0还是1.1.
-
- 除了请求⾏还有请求的头部字段, 这⾥是以key-value的形式存在, 包含多个键值对
-
- 还有就是实体主体, 在get请求时没有这⼀块, 在POST请求时有.
-
- 关于响应报⽂也包含响应⾏、头部字段、以及实体主体. 在响应报⽂的响应⾏中存在着当前的版本、状态码、短语, 也就是描述信息.
2.12 常见的状态码
- 1xx: 目前是协议的中间状态, 还需要后续请求
-
- 100: 请求者应当继续发送请求, 服务端返回100表示已收到请求的第一部分, 正在等待剩余部分.
-
- 101: 切换请求协议, 客户端已要求服务端切换协议, 服务端已确认并准备切换. 如从HTTP切换到WebSocket
- 2xx: 表示请求成功
-
- 200: 请求成功, 有响应体, 服务器成功返回数据
-
- 204: 服务端成功处理了请求, 但没有返回任何内容(无内容)
-
- 205: 服务端成功处理了请求, 但没有返回任何内容(重置内容)
- 3xx: 表示重定向状态, 需要重新请求
-
- 301: 永久重定向, 会缓存
-
- 302: 临时重定向, 不会缓存
-
- 304: 协商缓存命中
- 4xx: 表示客户端请求报文错误
-
- 400: 请求错误, 服务端不理解请求的语法
-
- 403: 服务器禁止访问, 拒绝请求
-
- 404: 资源未找到, 请求的网页不存在
- 5xx: 表示服务端错误
-
- 500: 服务器端错误, 无法完成请求
-
- 503: 服务器繁忙(服务不可用, 由于超载或停机维护, 通常只是暂时状态)
-
- 504: 服务端作为网关或代理, 但是没有及时从上游服务器收到请求.(网关超时)
发文不易, 喜欢点赞的人更有好运气? :), 定期更新+关注不迷路~
ps:欢迎加入笔者18年建立的研究iOS审核及前沿技术的三千人扣群:662339934,坑位有限,备注“掘金网友”可被群管通过~
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END