第五章 网络 之 TCP/IP

文章目录

  • TCP
    • 什么是TCP协议?UDP协议?它们的区别?
    • 说一下TCP/IP三次握手,四次挥手的具体细节?
  • HTTP
    • 描述一下HTTP协议?
    • HTTP请求/响应报文?
      • HTTP方法?(请求报文)
        • 面试:POST与GET区别?
      • HTTP状态码?(响应报文)
      • HTTP首部?(请求 & 响应首部常用字段)
    • HTTP 缓存机制?
    • 浏览器缓存机制:cookie/session
    • HTTP1.0 & HTTP1.x & HTTP2.0区别是什么?
  • HTTPS
    • 描述一下HTTPS?
    • HTTPS 工作原理 / 连接 & 通信过程?
    • HTTPS与HTTP区别?
    • 对称加密 & 非对称加密?
  • Socket
    • 描述一下Socket?
    • Socket 通信模型 / 原理 / 连接过程?
    • Socket 使用?
    • 描述一下WebSocket?
    • Socket & WebSocket & HTTP 对比?
  • 数据传输格式
    • 序列化
    • JSON、XML 解析方式
  • Andorid 网络基础
    • HttpClient & HttpURLConnection
    • 常见网络框架总结

TCP

什么是TCP协议?UDP协议?它们的区别?

TCP/UDP协议为传输层协议,传输层用于向用户提供可靠的端到端(每个进程都用一个端口号唯一标识)的通信,通过提供流量控制和差错控制保证报文的正确传输。
传输单位是报文段或用户数据报。
主要协议包括TCP协议和UDP协议。

协议 TCP协议 UDP协议
简介 面向连接的、可靠的传输层协议。传输的数据无差错、不丢失、不重复、按序到达(有流量控制、拥塞控制、提供全双工通信) 无连接的、不可靠的传输层协议。尽最大努力交付,不保证可靠性
连接 面向连接(发送数据前三次握手建立连接,发送结束四次挥手释放连接) 无连接的
传输数据 面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块) 面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部)
交互 点对点(一对一) 一对一,一对多,多对多
大小 TCP首部(开销20字节,包括源端口号、目的端口号等以及确认ACK、同步SYN、终止FIN等用于连接建立与数据传输)+TCP数据部分 UDP首部开销8字节(包括源端口号、目的端口号等)+UDP数据部分
适用情景 TCP用于在传输层有必要实现可靠传输的情景 UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信:1.包总量较少的通信(DNS、SNMP等)2.视频、音频等多媒体通信(即时通信)3.限定于LAN等特定网络中的应用通信4.广播通信(广播、多播)
传输 可靠传输:
(1)传输信道无差错,保证传输数据正确;
(2)不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据;
可靠性原理:
(1)使用三次握手建立TCP连接,四次握手释放TCP连接,保证建立的传输信道是可靠的。
(2)使用连续ARQ协议(超时自动重传:如果一个已经发送的报文段在超时时间内没没有收到确认,那么就重传这个报文段)来保证数据传输的正确性,
(3)使用滑动窗口协议来保证接收方能够及时处理所接收到的数据,进行流量控制
(4)使用慢开始、拥塞避免、快重传和快恢复来进行拥塞控制,避免网络拥塞
不可靠传输:
UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务
并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。
即使是出现网络拥堵的情况,UDP也无法进行流量控制等避免网络拥塞行为。
此外传输途中出现丢包,UDP也不负责重发(发送后不管其是否会到达接收方)。甚至当包的到达顺序出现乱序也没有纠正的功能。
如果需要以上的细节控制,不得不交由采用UDP的应用程序去处理。
协议 FTP、HTTP、POP3、TELNET… SMTP(网络管理)、DNS(域名转换)、TFTP(文件传输)、NFS(远程文件服务器)、DHCP…

说一下TCP/IP三次握手,四次挥手的具体细节?

  1. 报文段标识符
  • 确认ACK :TCP协议规定只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
  • 同步SYN:在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1,因此SYN置1就表示这是一个连接请求或连接接受报文。
  • 终止FIN:用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
  • 序号seq:用于对字节流进行编号。例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。
  • 确认号ack:期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
  1. 三次握手
    最初两端的TCP进程都处于CLOSED关闭状态,Client(A)主动打开连接,而Server(B)处于LISTEN(监听状态),等待A的连接请求并被动打开连接(由客户端执行connect触发)。
  • 第一次握手:由Client发出请求连接数据包: SYN=1 ACK=0 seq=x(TCP规定SYN=1时不能携带数据,但要消耗一个序号,因此声明自己的序号是 seq=x)此时Client进入SYN-SENT(同步已发送)状态,等待Server确认;
  • 第二次握手:Server收到请求报文后,如果统一建立连接,则向A发送连接确认报文,即 SYN=1 ACK=1 seq=y,ack=x+1,此时Server进入SYN-RCVD(同步收到)状态;
  • 第三次握手:Client收到Server的确认(SYN+ACK)后,向Server发出确认报文段,即 ACK=1,seq=x+1, ack=y+1,TCP连接已经建立,Client进入ESTABLISHED(已建立连接)状态;
    Server收到Client的确认后,也进入ESTABLISHED状态,完成三次握手;此时Client和Server可以开始传输数据。
    第五章 网络 之 TCP/IP_第1张图片
    (理解版)
    我们假设A和B是通信的双方。我理解的握手实际上就是通信,发一次信息就是进行一次握手。则对于三次握手:
    第一次握手: A给B打电话说,你可以听到我说话吗?
    第二次握手: B收到了A的信息,然后对A说: 我可以听得到你说话啊,你能听得到我说话吗?
    第三次握手: A收到了B的信息,然后说可以的,我要给你发信息啦!
    在三次握手之后,A和B都能确定这么一件事: 我说的话,你能听到; 你说的话,我也能听到。 这样,就可以开始正常通信了。
    如果两次,那么B无法确定B的信息A是否能收到,所以如果B先说话,可能后面的A都收不到,会出现问题 。
    如果四次,那么就造成了浪费,因为在三次结束之后,就已经可以保证A可以给B发信息,A可以收到B的信息; B可以给A发信息,B可以收到A的信息。
  1. 四次挥手
    数据传输结束后,通信的双方都可释放连接,A和B都处于ESTABLISHED状态。当Client没有数据再需要发送给服务端时,就需要释放客户端的连接,整个过程为:
  • 第一次挥手:当Client发起终止连接请求的时候,会发送一个(FIN为1,seq=u)的没有数据的报文,这时Client停止发送数据(但仍可以接受数据) ,进入FIN_WAIT1(终止等待1)状态,等待Server确认
  • 第二次挥手:Server收到连接释放报文后会给Client一个确认报文段(ACK=1,ack=u+1,seq=v), 进入CLOSE-WAIT(关闭等待)状态
    Client收到Server的确认后进入FIN_WAIT2状态,等待Server请求释放连接,Server仍可向Client发送数据。
  • 第三次挥手:Server数据发送完成后,向Client发起请求连接释放报文(FIN=1,ACK=1,seq=w,ack = u+1),Server进入LAST-ACK(最后确认)状态,等待Client确认
  • 第四次挥手:Client收到连接释放报文段后,回复一个确认报文段(ACK=1,seq=u+1,ack=w+1),进入 TIME_WAIT(时间等待) 状态,Server收到后进入CLOSED(连接关闭)状态。经过等待2MSL 时间(最大报文生存时间),Client进入CLOSED状态。
    第五章 网络 之 TCP/IP_第2张图片
    (理解版)
    A:“喂,我不说了 (FIN)。”A->FIN_WAIT1
    B:“我知道了(ACK)。等下,上一句还没说完。Balabala……(传输数据)”B->CLOSE_WAIT | A->FIN_WAIT2
    B:”好了,说完了,我也不说了(FIN)。”B->LAST_ACK
    A:”我知道了(ACK)。”A->TIME_WAIT | B->CLOSED
    A等待2MSL,保证B收到了消息,否则重说一次”我知道了”,A->CLOSED
    这样,通过四次挥手,可以把该说的话都说完,并且A和B都知道自己没话说了,对方也没花说了,然后就挂掉电话(断开链接)了 。
  1. 面试问题
  • 为什么需要握手?
    这里就引出了 TCP 与 UDP 的一个基本区别, TCP 是可靠通信协议, 而 UDP 是不可靠通信协议。
    TCP 的可靠性含义: 接收方收到的数据是完整, 有序, 无差错的。
    UDP 不可靠性含义: 接收方接收到的数据可能存在部分丢失, 顺序也不一定能保证。
    UDP 和 TCP 协议都是基于同样的互联网基础设施, 且都基于 IP 协议实现, 互联网基础设施中对于数据包的发送过程是会发生丢包现象的, 为什么 TCP 就可以实现可靠传输, 而 UDP 不行?
  • 为什么需要三次握手?
    为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。
    如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。
  • 为什么需要四次挥手?
    为了让服务器发送还未传送完毕的数据。只有传送完毕后,服务器会发送FIN连接释放报文。
    因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET(服务端数据未传输完毕),FIN报文仅仅表示Client没有需要发送的数据,但是仍能接受数据,Server的数据未必全部发送出去,需要等待Server的数据发送完毕后发送FIN报文给Client才能表示同意关闭连接。
    所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

建立连接时候ACK和SYN可以放在一个报文里发送给客户端。
连接关闭时ACK和FIN一般分开发送。

  • 为什么A在TIME-WAIT状态必须等待2MSL的时间?
    MSL最长报文段寿命Maximum Segment Lifetime,MSL=2
    客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
  • 保证A发送的最后一个ACK报文段能够到达B。
    如果 B 没收到 A 发送来的确认报文(A发送的最后一个ACK报文段可能丢失),那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
  • 防止“防止本次已失效的连接请求报文段出现在新的连接中。
    等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
  1. 整体通信流程
    第五章 网络 之 TCP/IP_第3张图片

HTTP

描述一下HTTP协议?

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从万维网(WWW)Web服务器 传输超文本到 本地客户浏览器 的传输协议。
在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。
HTTP协议特点:

  • 基于TCP/IP通信协议传递数据(HTML、图片文件,查询结果等)
  • 属于应用层协议
  • 采用客户端-服务端(请求-响应 C/S)工作方式,具体工作流程如下:
    第五章 网络 之 TCP/IP_第4张图片

HTTP请求/响应报文?

HTTP在应用层通过报文交互数据,分为请求报文和响应报文,分别用于发送请求&响应请求。

  • 请求报文
    第五章 网络 之 TCP/IP_第5张图片

    第五章 网络 之 TCP/IP_第6张图片
  • 响应报文
    第五章 网络 之 TCP/IP_第7张图片

    第五章 网络 之 TCP/IP_第8张图片

HTTP方法?(请求报文)

客户端发送的 请求报文 第一行为请求行,包含了方法字段。

请求方法 用法 说明
OPTIONS 返回服务器针对特定资源所支持的HTTP请求方法 返回:Allow: GET,POST,HEAD等
HEAD 获取报文首部 与GET方法类似,但不返回报文实体主体部分。用于确认URL的有效性以及资源更新日期时间等
GET 获取资源 当前网络请求中,绝大部分使用GET方法
POST 传输实体主体 向指定资源传输数据(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改
PUT 上传文件 由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法
PUT /new.html HTTP/1.1
DELETE 删除文件 与 PUT 功能相反,并且同样不带验证机制
DELETE /file.html HTTP/1.1
TRACE 追踪路径 回显服务器收到的请求,主要用于测试或诊断。

面试:POST与GET区别?

GET提交 POST提交
作用 获取资源 传输实体数据
参数位置 附在URL之后(将数据放在HTTP请求行),以?代表URL结尾,多个参数用&连接。例如:login.action?name=chy&password=123 提交的数据放在HTTP报文的请求体中
参数长度 提交的数据大小有限制(因为浏览器对URL的长度有限制) 提交的数据没有限制(GET提交的数据会在地址栏中显示,而POST提交,地址不会改变)
参数形式 键值对形式(作为查询字符串) 表单形式,因此必须将Content-type设置为:application/x-www-form- urlencoded
参数类型 只允许ASCII字符 任何类型
安全性 安全性低
请求参数直接在URL上可见
报文可缓存在浏览器内
安全性高
请求参数在HTTP请求数据中
浏览器无缓存
应用场景 传递小量、不敏感的数据。用于从指定资源请求数据 传递大量、敏感数据。用于向指定资源提交数据
实例 GET /bookes/?name=chy&password=123 HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 Gecko/20050225
Connection: Keep-Alive
POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 Gecko/20050225
Content-type: application/x-www-form- urlencoded
Connection: Keep-Alive
name=chy&password=123

HTTP状态码?(响应报文)

服务器返回的 响应报文 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。

状态码 类别 含义 常见类型
1xx Informational(信息性状态码) 接收的请求正在处理
2xx Success(成功状态码) 请求正常处理完毕 200:OK
3xx Redirection(重定向状态码) 需要进行附加操作以完成请求 304 Not Modified :如果请求报文首部包含例如:If-None-Match,If-Modified-Since等HTTP缓存相关数据
当服务器数据未修改时,则返回304告知客户可以使用缓存数据
4xx Client Error(客户端错误状态码) 服务器无法处理请求 400 Bad Request:请求报文出现语法错误
403 Forbidden:请求被拒绝
404 Not Found:没有找到服务器
5xx Server Error(服务器错误状态码) 服务器处理请求出错 500 Internal Server Error:服务器正在执行请求时内部发生错误

HTTP首部?(请求 & 响应首部常用字段)

有 4 种类型的首部字段:通用首部字段、请求首部字段、响应首部字段和实体首部字段。

  • 请求 & 响应报文 的 通用首部字段
首部字段名 用法 说明
Cache-Control 指定请求和响应遵循的缓存机制 取值一般为no-cache或max-age=XX(XX为整数,表示资源缓存有效期(秒))
Content-Type 请求体/响应体类型 text/plain:数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符
application/json(x-www-form-urlencoded):数据被编码为名称/值对。是标准的编码格式,如消息主体是序列化后的JSON字符串
multipart/form-data:数据被编码为一条消息,页上的每个控件对应消息中的一个部分,如文件上传
Content-Length 请求体/响应体长度 单位字节
Content-Encoding 请求体/响应体编码格式 如gzip,deflate
Accept 说明接收的类型。可以多个值,用,分开 Accept:text/plain,text/html
Accept-Encoding 告诉对方我方接受的Content-Encoding 如gzip,deflate
ETag 当前资源的标识 与Last-Modified、If-None-Match、If-Modified-Since配合,用于缓存控制
  • 请求报文 的 请求首部字段
    第五章 网络 之 TCP/IP_第9张图片

  • 响应报文 的 响应首部字段
    第五章 网络 之 TCP/IP_第10张图片

  • 实体首部字段

首部字段名 用法
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体使用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间

HTTP 缓存机制?

  • 浏览器第一次请求
    第五章 网络 之 TCP/IP_第11张图片
    在浏览器第一次请求数据时,此时缓存数据库中没有对应的缓存数据,需要请求服务器,服务器返回相应的数据(主体body)和缓存规则(响应头Header)后,浏览器将数据和缓存规则存储至缓存数据库中。
    HTTP缓存规则包括:Expires、Cache-Control(强制缓存规则),Etag、Last-Modified(对比缓存规则)
    第五章 网络 之 TCP/IP_第12张图片
  • 浏览器第二次请求
    第五章 网络 之 TCP/IP_第13张图片
    浏览器第二次请求数据时,会根据是否需要向服务器发起请求分为 强制缓存 & 对比缓存
  1. 首先执行强制缓存,服务器响应浏览器一个缓存时间(Expires/Cache-Control)
  • Expires:服务器返回的到期时间。
  • Cache-Control:
Cache-Control类型 描述
private 客户端可缓存
public 客户端和代理服务器均可缓存
max-age = xxx 缓存内容在xxx秒后失效
no-cache 需要使用对比缓存来验证缓存数据
no-store 所有内容均不会缓存,不出发强制缓存与对比缓存
  1. 如果强制缓存命中(在缓存时间内),则直接使用缓存,不需与服务器发生交互,不再执行对比缓存规则。
  2. 若超出缓存时间,则执行比较缓存策略。
    第五章 网络 之 TCP/IP_第14张图片
  3. 再执行比较缓存策略,浏览器将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验
  • Last-Modified/If-Modified-Since:
    Last-Modified 为服务器相应请求时,告诉浏览器资源的最后修改时间。当浏览器再次请求服务器时,将在请求中添加参数 If-Modified-Since(值为上次响应里面的Last-Modified值),服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。
    若资源的最后修改时间 大于 If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;若资源的最后修改时间 小于或等于 If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
  • Etag/If-None-Match:
    Etag 为服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。服务器收到请求后发现有头If-None-Match 则与被请求资源的唯一标识进行比对。
    若不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

为什么比较校验要访问服务器?
服务端在进行标识比较后,只返回header部分,通过状态码通知客户端使用缓存,不再需要将报文主体部分返回给客户端。因此报文大小和请求时间打打减少

第五章 网络 之 TCP/IP_第15张图片

浏览器缓存机制:cookie/session

cookie & session均是解决HTTP无状态协议的一种记录客户状态的机制。
cookie——客户端的通行证
Cookie 是服务器发送到用户浏览器并保存在本地浏览器的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。
创建过程:

  1. 服务器发送的响应报文包含 Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中。
  2. 客户端之后对同一个服务器发送请求时,会从浏览器中取出 Cookie 信息并通过 Cookie 请求首部字段发送给服务器。

session——服务端的客户档案
除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。
Session 可以存储在服务器上的文件、数据库或者内存中。也可以将 Session 存储在 Redis 这种内存型数据库中,效率会更高。
使用 Session 维护用户登录状态的过程如下:

  1. 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
    服务器验证该用户名和密码,如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
  2. 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;
  3. 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。

cookie 与 session 区别

cookie session
存放位置 客户端 服务端
存储数据 只能存储 ASCII 码字符串 可以存储任何类型数据(考虑存储数据的复杂性)
安全性 低(存储在浏览器中,对用户可见,容易被恶意查看、修改) 高(session存储在服务器上,不存在敏感信息泄露的风险)
开销 较小 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。

HTTP1.0 & HTTP1.x & HTTP2.0区别是什么?

协议 HTTP1.0 HTTP1.X HTTP2.0
特点 无状态、无连接
HTTP1.0规定浏览器和服务器保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器处理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。
1. 持久连接:通过请求管道化实现,多个http 请求可以复用一个TCP连接,服务器端按照FIFO原则来处理不同的Request(实现"并行"传输)
2. 缓存处理:cache-control
3. 一个服务器能够创建多个Web站点:Host
4. 断点续传、身份认证、状态管理等
1. 二进制分帧:在应用层和传输层之间增加一个二进制分帧,在不改动 HTTP/1.x 的语义、方法、状态码、URI 以及首部字段的情况下, 解决了HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量
2. 实现多路复用:多路复用允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息。即HTTP/2 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流,实现真正的并行传输
3. 头部压缩
4. 服务器推送:是一种在客户端请求之前发送数据的机制。
痛点 连接无法复用:每次请求都要经历三次握手和慢启动
队头阻塞:由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,同样的后面的请求也给阻塞了
请求管道化并没有真正地实现"并行",且在 HTTP/1.1 协议中浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制。超过限制数目的请求会被阻塞

图1为短连接(http 1.0),图2为持久连接(多路复用 http 2.0),图3为持久连接(管道化http 1.1)
第五章 网络 之 TCP/IP_第16张图片

HTTPS

描述一下HTTPS?

  • HTTP传输数据的安全性问题
  • 使用明文进行通信,内容可能会被窃听;
  • 不验证通信方的身份,通信方的身份有可能遭遇伪装;
  • 无法证明报文的完整性,报文有可能遭篡改。
  • HTTPS简介
    HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)不是新协议,是以安全为目标的HTTP通道,可理解为HTTP的加强版。实现原理是让 HTTP 先和 SSL(Secure Sockets Layer 安全套接字层,TLS(传输层安全)是更为安全的升级版 SSL)通信,再由 SSL 和 TCP 通信,也就是说 HTTPS 使用了SSL/TLS建立信道,加密数据包。
    通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。
    第五章 网络 之 TCP/IP_第17张图片
    HTTPS特点:
  • 内容加密:采用混合加密技术,中间者无法直接查看明文内容。
    混合加密:结合对称加密和非对称加密技术。使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。所以网络上传输的数据是被对称加密过的密文和用非对称加密后的密钥。即使被黑客截取。由于没有私钥,所以无法获取加密明文的密钥,也无法获取明文数据。
  • 身份认证:确保浏览器访问的网站是经过CA(数字证书认证机构)验证的可信任网站。
  • 数据完整性:SSL 提供报文摘要功能来进行完整性保护。

报文摘要:用于对发送的报文生成一个非常小的摘要信息。这个摘要信息保证原报文的完整性,即原报文只要有一位被改变,则摘要信息就会不匹配。

HTTPS 工作原理 / 连接 & 通信过程?

  • 对称加密
    使用一个密钥加密,使用相同的密钥才能解密。计算量小,加密解密速度快,但在传输加密数据时需传输密钥,密钥容易泄露,安全性低。
  • 非对称加密
    有一个公钥,一个私钥。公钥加密只能私钥解密,私钥加密只能公钥解密。计算量大,加密解密速度慢,在传输数据时只需传输公钥和公钥加密的数据,即时被截取,由于没有私钥所以无法获取明文数据,安全性高。
  • HTTPS工作原理(SSL/TLS认证+加密过程)
    发送方将对称加密的密钥通过非对称加密的公钥进行加密,接收方使用私钥进行解密得到对称加密的密钥,再通过对称加密交换数据。Https协议通过对称加密(传输快,传输交换数据)和非对称加密(安全,传输密钥)结合处理实现的。
  1. 浏览器发起往服务器的443端口发起请求"https://www.baidu.com"(及之后的对称加密算法)。
  2. 服务器中有公钥和私钥,收到请求,会将公钥服务器身份认证信息通过SSL数字证书返回给浏览器(证书包含公钥和身份认证信息);

服务端,都有公钥、私钥和证书:
证书用来对通信方进行身份认证的。一般证书包含公钥以及身份认证信息。这里的证书可以是向某个权威机构申请的,也可以是自制的。区别在于自己办法的证书需要客户端验证通过,才可以继续访问;而使用受信任的公司申请的证书则不会弹出提示页面。
数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。
服务器的运营人员向 CA 提出公开密钥的申请,CA 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。
进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。

  1. 浏览器进入数字证书认证环节,这一部分是浏览器内置的TLS完成的:
    (1)证书可信度认证:首先浏览器会从内置的证书列表中索引,找到服务器下发证书对应的机构,如果没有找到,此时就会警告用户该证书不是由权威机构颁发,是不可信任的(浏览器显示https警告)。如果查到了对应的机构,则取出该机构颁发的证书公钥
    (2)服务端身份认证:用机构的证书公钥解密得到证书的内容和证书签名,内容包括网站的网址、网站的公钥、证书的有效期等。浏览器会先验证证书签名的合法性。签名通过后,浏览器验证证书记录的网址是否和当前网址是一致的,不一致会警告用户。如果网址一致会检查证书有效期,证书过期了也会警告用户。这些都通过认证时,浏览器就可以安全使用证书中的网站公钥了。
    (3)浏览器生成一个随机数R,并使用证书公钥对R进行加密。(R就是之后数据传输的对称密钥)
  2. 浏览器将加密的R传送给服务器。
  3. 服务器用自己的私钥解密得到R。
  4. 服务器以R为密钥使用了对称加密算法加密网页内容并传输给浏览器。
  5. 浏览器以R为密钥使用对应的对称解密算法获取网页内容。
    第五章 网络 之 TCP/IP_第18张图片
  • HTTPS中那里使用对称加密?哪里使用非对称加密
    前5步其实就是HTTPS的握手过程,这个过程主要是认证服务端证书的合法性。
    因为非对称加密计算量较大,整个通信过程只会用到一次非对称加密算法(主要是用来保护传输客户端生成的用于对称加密的随机数私钥)。后续内容的加解密都是通过一开始约定好的对称加密算法进行的。
    握手过程采用了一次非对称加密,对对称密钥加密。使得浏览器与服务器双方知道传输数据过程对称加密算法的规则。
    数据传输过程采用多次对称加密,对传输数据加密。浏览器和服务器用握手过程获得的对称加密规则加密/解密传输数据。

HTTPS与HTTP区别?

HTTP HTTPS
定义 超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议 HTTPS是身披SSL外壳的HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性
成本 成本低 服务器的运营人员需要向CA申请证书,SSL的专业证书需要购买,功能越强大,费用越高
安全性 安全性较低 HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全,防止数据在传输过程中被窃取,确保数据的完整性
端口 80 443
效率 效率较高 因为需要进行加密解密等过程,因此速度会更慢

对称加密 & 非对称加密?

加密算法 对称加密 非对称加密
原理 加密算法是公开的,靠的是密钥来加密数据。使用一个密钥加密,使用相同的密钥才能解密 加密算法是公开的,有一个公钥,一个私钥(公钥和私钥不是随机的,由加密算法生成);公钥加密只能私钥解密,私钥加密只能公钥解密,加密解密需要不同密钥
常用算法 DES,3DES,AES RSA
优点 计算量小,加密和解密速度较快,适合加密较大数据 可以传输公钥(服务器—>客户端)和公钥加密的数据(客户端->服务器),数据传输安全
缺点 在传输加密数据之前需要传递密钥,密钥传输容易泄露;一个用户需要对应一个密钥,服务器管理密钥比较麻烦 计算量大,加密和解密速度慢

Socket

描述一下Socket?

Socket 即 套接字,是通信的基石,是应用层 与 TCP/IP 协议族通信的中间软件抽象层,本质为一个封装了 TCP / IP协议族 的编程接口(属于传输层)。网络上的两个进程端口通过Socket实现一个双向的通信连接从而进行数据交换。
第五章 网络 之 TCP/IP_第19张图片

  • 表示
    Socket是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用协议、(本地主机IP地址,本地进程的协议端口)、(远地主机IP地址,远地进程协议端口)。
    Socket一般成对出现,一对套接字(其中一个运行在服务端一个运行在客户端)
Socket ={(IP地址1:PORT端口号)(IP地址2:PORT端口号)}
  • 适用场景:即时通讯,替代轮询
    网站上的即时通讯是很常见的,比如网页的QQ,聊天系统等。按照以往的技术能力通常是采用轮询、Comet技术解决。
    HTTP协议是非持久化的,单向的网络协议,在建立连接后只允许浏览器向服务器发出请求后,服务器才能返回相应的数据。当需要即时通讯时,通过轮询在特定的时间间隔(如1秒),由浏览器向服务器发送Request请求,然后将最新的数据返回给浏览器。这样的方法最明显的缺点就是需要不断的发送请求,而且通常HTTP request的Header是非常长的,为了传输一个很小的数据 需要付出巨大的代价,是很不合算的,占用了很多的宽带。
    缺点:会导致过多不必要的请求,浪费流量和服务器资源,每一次请求、应答,都浪费了一定流量在相同的头部信息上
    然而WebSocket的出现可以弥补这一缺点。在WebSocket中,只需要服务器和浏览器通过HTTP协议进行一个握手的动作,然后单独建立一条TCP的通信通道进行数据的传送。

Socket 通信模型 / 原理 / 连接过程?

ServerSocket:服务器端类
Socket:客户端类
服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。
第五章 网络 之 TCP/IP_第20张图片
(1)连接过程

  • 服务端监听
    服务端创建 ServerSocket 实例,绑定监听的端口;调用accept()方法,进入等待状态,等待客户请求
ServerSocket ss =new ServerSocket(30000);
Socket s = ss.accept();
  • 客户端请求
    客户端创建 Socket 实例,指明需要连接的服务端IP地址和端口号(即指明需要连接服务端套接字),并向服务端Socket提出连接请求
Socket s = new Socket("192.168.1.88",30000); 
  • 连接确认
    当 服务端Socket 监听到 客户端Socket 的连接请求后,为该连接创建一个服务端Socket。此时连接就建立好了。

(2)通信过程

  • 连接建立后,服务端/客户端通过入流InputStream读取接收到的数据;通过OutputStream向对方发送信息。
  • 调用close()方法关闭相应资源

Socket 使用?

(1)使用 ServerSocket 创建服务端

public class SocketServer {
    public static void main(String[] args) throws IOException {
        //1. 创建一个服务器端Socket,即ServerSocket对象,指定绑定的端口,并监听此端口
        ServerSocket serverSocket = new ServerSocket(12345);
        InetAddress address = InetAddress.getLocalHost();
        String ip = address.getHostAddress();
        Socket socket = null;
        //2. 调用accept()等待客户端连接
        System.out.println("~~~服务端已就绪,等待客户端接入~,服务端ip地址: " + ip);
        socket = serverSocket.accept();
        //3. 连接建立后,通过输入流InputStream读取接收到的数据
        InputStream is=null;
        InputStreamReader isr=null;
        BufferedReader br=null;
        //4. 通过输出流OutputStream向客户端发送响应信息
        OutputStream os=null;
        PrintWriter pw=null;
        is = socket.getInputStream();     //获取输入流
        isr = new InputStreamReader(is,"UTF-8");
        br = new BufferedReader(isr);
        String info = null;
        while((info=br.readLine())!=null){
        	//循环读取客户端的信息
            System.out.println("客户端发送过来的信息" + info);
        }
        socket.shutdownInput();//关闭输入流
        //5. 调用close()方法关闭相关资源
        socket.close();
    }
}

(2)使用 Socket 创建客户端

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_accept = (Button) findViewById(R.id.btn_accept);
        btn_accept.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        new Thread() {
            @Override
            public void run() {
                try {
                    acceptServer();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private void acceptServer() throws IOException {
        //1. 创建客户端Socket,指定服务器ip地址和端口
        Socket socket = new Socket("172.16.2.54", 12345);
        //2. 连接建立后,通过输出流OutputStream向服务器发送请求信息
        //3. 通过输入流InputStream获取服务器响应的信息
        OutputStream os = socket.getOutputStream();//字节输出流
        PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
        // 获取客户端的IP地址
        InetAddress address = InetAddress.getLocalHost();
        String ip = address.getHostAddress();
        pw.write("客户端:~" + ip + "~ 接入服务器!!");
        pw.flush();
        socket.shutdownOutput();//关闭输出流
        //4. 调用close()方法关闭套接字
        socket.close();
    }}
}}

描述一下WebSocket?

WebSocket是HTML5一种新的协议。它借鉴了Socket这种思想,为web应用程序客户端和服务端之间(注意是客户端服务端)提供了一种全双工通信机制(full-duplex)。同时,它又是一种新的应用层协议。一开始的握手需要借助HTTP请求完成。
WebSocket同HTTP一样也是应用层的协议,但是它是一种双向通信协议,是建立在TCP之上的。连接过程需要进行握手:

  1. 浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。
  2. TCP连接成功后,需要进行浏览器与服务器的一次握手(开始前的HTTP握手):
    • 浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。
    • 服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。
  3. 当收到了连接成功的消息后,通过TCP通道进行传输通信。并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
第五章 网络 之 TCP/IP_第21张图片

         function WebSocketTest()
         {
            if ("WebSocket" in window)	// 浏览器支持WebSocket
            {
               // 打开一个 web socket
               // Websocket 使用 ws 或 wss 的统一资源标志符,类似于 HTTPS,其中 wss 表示在 TLS 之上的 Websocket。如:
               // ws://example.com/wsapi	Websocket与HTTP使用相同的TCP端口:80端口
			   // wss://secure.example.com/ 运行TLS上时,默认使用443端口
               var ws = new WebSocket("ws://localhost:9998/echo");
                
               ws.onopen = function()
               {
                  ws.send("发送数据");
               };
                
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
               };
                
               ws.onclose = function()
               { // 连接关闭
               };
            }
         }

Socket & WebSocket & HTTP 对比?

Socket WebSocket HTTP
定义 封装了 TCP / IP协议族 的编程接口(API) 借鉴了Socket这种思想,为web服务器和浏览器之间提供了一种全双工通信机制的数据传输协议 利用TCP在Web服务器和浏览器之间数据传输的协议
工作层 传输层 应用层
数据传输 全双工通信机制(双向)
即建立网络连接后,通信双方都能主动向对方发送或接受数据,直到双方连接断开。即服务器可主动发送消息给客户端,实现信息的主动推送;而不需要由客户端向服务器发送请求
请求-响应(单向)
客户端向服务端发送请求后,服务端才能向客户端返回数据
持久性 持久化
(Socket 的 TCP 长连接的通讯模式:一旦 Socket 连接建立后,后续数据都以帧序列的形式传输。在客户端或服务端断开Socket 连接前,不需要客户端和服务端重新发起连接请求。)
非持久化
连接建立 & 数据传输 1. 创建ServerSocket对象,绑定监听的端口
2. 调用accept()方法监听客户端的请求
3. 连接建立后,通过输入流InputStream、OutputStream进行数据交互
TCP连接建立后,借助HTTP协议进行WebSocket三次握手,之后数据传输使用WebSocket协议 TCP连接建立后,客户端发送请求报文,服务端返回响应报文

数据传输格式

序列化

序列化:把java对象转化为二进制字节码写入IO流中。
反序列化:将IO流中的二进制字节恢复成java对象。
序列化机制允许将实现序列化的Java对象转换位字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
应用场景:

  • 所有可在网络上传输的对象都必须是可序列化的。
  • 所有需要保存到磁盘的java对象都必须是可序列化的。

通常建议:程序创建的每个JavaBean类都实现Serializeable接口

JSON、XML 解析方式

  • Json
    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。
  • 代码格式
{
    "name": "中国",
    "province": [{
        "name": "黑龙江",
        "cities": {
            "city": ["哈尔滨", "大庆"]
        }
    }, {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }]
}
  • 解析方式
解析方式 JSONObject FastJson Gson
介绍 原生 阿里巴巴FastJson是一个Json处理工具包 GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库
序列化 String jsonStr = jsonObject.toString();
String jsonStr = jsonArray.toString();
String jsonString = JSON.toJSONString(person); String gsonString = gson.toJson(object);
反序列化 JSONObject jsonObject = new JSONObject(jsonStr);
JSONArray jsonArray = new JSONArray(jsonStr);
person =JSON.parseObject(jsonString,Person.class);
List persons2 = JSON.parseArray(jsonString,Person.class);
T t = gson.fromJson(gsonString, cls);
特点 性能好,速度快 功能全面
  • XML
  • 代码格式


    中国
    
        黑龙江
        
            哈尔滨
            大庆
        
    
     
        广东
        
            广州
            深圳
            珠海
        
    

  • 解析方式
  1. Dom
  2. Sax
  3. Pull

Andorid 网络基础

HttpClient & HttpURLConnection

Android主要提供了两种方式进行网络请求:HttpClient与HttpUrlConnection。

HttpClient HttpUrlConnection
相同 都支持https协议,以流的形式进行上传和下载、配置超时事件、IPV6、以及连接池等功能。
不同 拥有众多API,实现较稳定,bug数量少。但难以扩展,维护成本高。Android6.0后被移除。 提供简单、轻量级API,易于扩展。但Android2.2前有个重大bug。2.3后修改了bug并且提供了压缩和缓存机制,有效提升了网络性能。

常见网络框架总结

  • Volley
    Volley是Google推出的网络通信框架,适合数据量小但通信频繁的网络操作。但不适合大文件下载。
    特点是:(1)可进行Post、Get网络请求与图像异步处理请求(2)对网络请求进行排序与优先级处理(3)对网络请求进行缓存(4)多级别取消请求(5)与Activity生命周期联动
    它的工作原理是先将请求加入缓存队列,并通过cacheDispatcher查询本地是否缓存本次请求结果,如果命中,则从缓存中解析结果并返回主线程;如果没有命中则将请求添加到网络队列,并通过networkDispatcher发送网络请求,获得并解析响应结果,将结果写入缓存并返回主线程。
  • OkHttp
    OkHttp是Square团队开发的支持Http2/SPDY的网络通信框架,即支持共享同一个Socket处理同一个服务器的所有请求,若SPDY不可用,则通过连接池来减少请求延时。支持重连机制、缓存响应数据及GZIP减少数据流量。
    OkHttp核心设计模式是拦截器责任链模式,采用责任链的模式来使每个功能分开,每个拦截器自行完成自己的任务,并且将不属于自己的任务交给下一个,简化了各自的责任和逻辑,实现了网络请求。这样设计的好处在于使每个责任链可以分层实现缓存、压缩、网络IO和请求等功能,并且可以对响应的数据做其他的逻辑处理。
    OkHttp适用于数据量大的重量级网络请求。
  • Retrofit
    Retrofit是基于RESTful风格推出的网络请求框架封装,是基于OKHttp的网络请求框架的二次封装。其底层是通过OKHttp进行网络请求,而Retrofit仅负责网络请求接口的封装,从而简化了用户网络请求的参数配置,还能与Rxjava结合。
    Retrofit采用了大量设计模式封装OkHttp,它的核心工作原理是将Http请求抽象为Java接口,在接口中用注解描述和配置网络请求参数。Retrofit使用动态代理的方式,动态地将网络请求接口的注解解析成HTTP请求。最终通过OKHttp执行Http请求。
    Retrofit在任何场景下都优先选择,尤其是后台Api遵循RESTful风格且项目中使用RxJava的场景。

你可能感兴趣的:(Android面试之旅,Java面试之旅)