iOS老司机的网络相关Tips

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情

1. 前言: 作为一个有自我修养的iOS工程师, 对网络的理解体现在开发中的方方面面

  • 如果你是个科班毕业的iOS开发者, 对计算机网络的基础认识可能是通过<<计算机网络>>这本教材.
    image.png
  • 如果你是个其他专业转向iOS的开发者, 对计算机网络的认识可能来自于这本无数大佬安利的<<图解HTTP>>
    image.png
  • 下面就由我们来结合iOS开发日常工作中的方方面, 来一起对iOS中常用的网络相关知识做一个不成体系的梳理, 抛砖引玉, 如在阅读过程中发现错误, 请及时在评论区交流指正:)

2. iOS开发中的网络相关基操Tips

2.1 HTTP的请求方式有哪些?

image.png

  • 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的流量控制与拥塞控制

image.png

  • TCP的流量控制是通过滑动窗⼝协议来实现的. TCP协议报⽂头包含16位的窗⼝⼤⼩, 接收⽅在返回ACK时会把⾃⼰的即时窗⼝填⼊, 发送⽅就根据报⽂中窗⼝的⼤⼩来控制发送的速度.
  • 拥塞控制是为了解决⽹络中涌⼊⼤量数据包的⼀种机制.
  • 这⾥主要使⽤慢开始, 拥塞避免和快恢复, 快重传两种策略.
    • 慢开始是指刚开始发送数据的时候, 拥塞窗⼝是1, 以后每次收到ACK后, 将拥塞窗⼝的值按照指数级增⻓, 当增⻓达到了拥塞窗⼝的⻔限值的时候, 就会以线性⽅式增⻓, 来控制发送数据的速度.
    • 当发送⽹络拥塞的时候, 就会将拥塞窗⼝值改为1, 重新开始慢开始的流程. 同时将拥塞窗⼝的⻔限值改为拥塞时的⼀半.
    • 快恢复快重传是基于慢开始的, 在发⽣⽹络拥塞的时候, 是把拥塞窗⼝的⼤⼩调到拥塞值的⼀半, 然后以线性⽅式增⻓.

2.6 DNS域名解析相关

image.png

  • DNS是做域名解析的, 我们在通过域名访问服务器的时候, ⾸先会通过DNS进⾏域名解析, 得到服务器的IP地址, 然后再进⾏访问.
  • 域名解析使⽤的UDP的⽅式进⾏明⽂传输的. 采⽤udp是因为它的速度更快.
  • 但是因为传输的明⽂, 所以容易遭到劫持.
  • 所以在解决DNS劫持的时候主要有两种⽅式, ⼀种是httpDNS, ⼀种是⻓连接.
    • httpDNS是指通过发送⼀个http请求来解析域名. 因为普通的DNS劫持是基于UDP的, 所以我们通过 httpDNS是采⽤TCP的⽅式, 可以防⽌.
    • ⻓连接的⽅式是指我们建⽴⼀个⻓连接服务器, 让client与中间服务器建⽴⻓连接, 并将⻓连接与域名解析服务器通过内⽹专线的⽅式进⾏连接, 以此来避免DNS的劫持.

2.7 如何保证Cookie的安全

image.png

  • 对cookie内容进⾏加密处理, 这种⽅式的缺点是不能避免脚本攻击.
  • 在https下传输cookie, 这也是我们使⽤最多的⽅式.
  • 设置cookie为httpOnly来防⽌跨站脚本攻击.

2.8 关于HTTPS

  • HTTPS是在HTTP的基础上增加了安全模块(TLS/SSL).

2.8.1 HTTPS的连接建立流程

image.png

  1. ⾸先client端将当前⽀持的TLS版本号, 以及⽀持的加密算法, 并⽣成⼀个随机数C⼀起发送给server端.
  2. server端收到消息后会选择⼀套加密算法, 并⽣成⼀个随机数S, 连同server证书返回给client端
  3. client端先校验server证书, 然后根据预主秘钥+C+S组装会话秘钥. 并通过server证书将预主秘钥加密发送给server端.
  4. server端⽤私钥进⾏解码, 得到预主秘钥后, 组装会话秘钥, 然后加密握⼿消息.

2.9 ISO模型的七层架构(应表会传网数物)

  • 七层架构分别是: 应⽤层、表示层、会话层、传输层、⽹络层、数据链路层、物理层.
  • 应⽤层: 最⾼层, 直接⾯对⽤户.
  • 表示层: ⽤来将数据转换成另外⼀种格式, ⽐如⽂字、视频、图⽚等.
  • 会话层: 负责建⽴和断开连接.
  • 传输层: TCP、UDP都属于这⼀层的协议.
  • ⽹络层: 定义了IP和⼦⽹掩码, ⽤来确定⽹段, 通过路由器和交换机进⾏传输. IP协议就是属于⽹络层的协议.
  • 数据链路层: 把⽐特流封装成数据帧的格式.
  • 物理层: 通过⽹线, 光缆等这种物理⽅式将电脑连接起来, 传递的是⽐特流.

2.10 什么是BIO/NIO/AIO?

  • BIO: 同步阻塞IO, 每⼀个客户端连接, 服务端都会对应⼀个处理线程, 对于没有分配到处理线程的连 接就会被阻塞或者拒绝. 相当于⼀个连接⼀个线程.

image.png

  • NIO: 同步⾮阻塞IO, 基于Reactor模型, 客户端和channel进⾏通信, channel可以进⾏读写操作. 通过多路复⽤器seletor来轮询注册在其上的channel, ⽽后再进⾏IO操作. 这样的话, 在进⾏IO操作的时候再⽤⼀个线程去处理就好. 也就是⼀个请求⼀个线程.

image.png

  • AIO: 异步⾮阻塞IO, 相⽐NIO更进⼀步, 完全有操作系统来完成请求的处理, 然后通知服务端开启线 程进⾏处理, 因此是⼀个有效请求⼀个线程.

2.11 浅谈一下对HTTP的理解

image.png

  • ⾸先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,坑位有限,备注“掘金网友”可被群管通过~

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYYQOg4D' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片