网络请求笔记
网络七层协议:OSI
Open System Interconnection 开放式系统互联参考模型
OSI从上到下:1~3为低三层,4~7为高三层,传输层有缓存作用,当网络层质量/连接速度/流量不满足会话层要求时,调整资源分配(分流/合流,复用/解复用技术),满足高层要求
- 7应用层》 对应应用程序的通信服务,如telnet,http,ftp,nfs,smtp
- 6表示层》 数据传输格式及加密,解决不同系统字符集不一致的问题,如ASCII传输,发送方把数据以ASCII方式加密再传输,接收方把接收的标准ASCII数据转换成接收方计算机的字符集
- 5会话层》 定义开始、控制和结束一个回会话,提供校验点,在通信失效是通过检验点恢复到原来的状态
- 4传输层》 包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同应用的数据流进行复用,还包括对收到的顺序不对的数据包的重新排序功能,提供流量控制,如TCP、UDP、SPX
- 3网络层》 定义端对端的包传输,能够标识所有节点的逻辑地址,路由实现和学习方式,为适应最大传输单元长度小于包长度的传输介质,还定义了如何将一个包分解成更小的包的分段方式,解决1对多,和多对多传输,寻址的问题,如IP、IPX
- 2数据链路层》定义在单个链路上如何传输数据,解决链接不稳定和数据丢失的问题,如ATM、FDDI
- 1物理层》 有关传输介质特性的规范,如Rj45、802.3
TCP协议:
头部格式
- Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接;
- Sequence Number:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题;
- Acknowledgment Number:32位确认***包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认***的字段才有效。主要用来解决不丢包的问题;
- Offset:给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;
- TCP Flags:TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为
URG
,ACK
,PSH
,RST
,SYN
,FIN
。每个标志位的意思如下:- URG:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;
- ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;
- PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;
- RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;
- SYN:表示同步序号,用来建立连接。
SYN
标志位和ACK
标志位搭配使用,当连接请求的时候,SYN
=1,ACK
=0;连接被响应的时候,SYN
=1,ACK
=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN
的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手; - FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送
FIN
标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
- Window:窗口大小,也就是有名的滑动窗口,用来进行流量控制。
三次握手:
- 客户端发送SYN(Synchronize Sequence Numbers 同步标识)包到服务端,syn=j,并进入SYN_SENT状态,等待服务端响应
- 服务端接收到SYN包,确认客户端的SYN,ack = j +1,并发送SYN(syn = k)+ACK(Acknowledgement Number 确认序号标识位)包给客户端,进入SYN_RECV状态
- 客户端接收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack = k+1)包,发送完成后,客户端和服务端都进入ESRABLISHED(TCP连接成功)状态,完成握手。
关闭TCP连接,四次分手:
- 当客户端程序通知客户端关闭TCP连接时,客户端发送带有FIN附加标记的报文段给服务端
- 服务端接收到客户端的关闭TCP请求,通知服务端程序该TCP将被关闭,并发送一个ACK包给客户端,为的时防止服务端程序关闭时客户端重传FIN报文段
- 服务端程序通知TCP关闭连接,服务端向客户端发送一个FIN报文段
- 客户端接收到FIN报文段后,向服务端发送ACK包表示连接已关闭,四次握手关闭TCP完成
HTTP是一个属于应用层的面向对象的协议,简捷、快速的方式适用于分布式超媒体信息系统,于1990年提出。
- 支持C/S,客户/服务器模式;
- 简单快速;
- 灵活,允许传输任意类型的数据对象,由Content-Type标记决定
- 无连接,完成一次应答后就断开连接
- 无状态,不会保存其它请求的信息,即每次要把需要的参数都上次一次,对不需要先前信息的应答更快速
HTTP URL:
http://host[":"port][abs_path]
通过HTTP协议来定位。host表示合法的Internet主机名或IP地址;post指定主机端口,为空使用默认端口80;abs_path指定请求资源URL,可以是任意资源;
HTTP请求报文:
CRLF表示回车和换行, 除了作为结尾的CRLF外,不允许出现单独的CR或LF字符
- 请求行: Method Request-URI HTTP-Version CRLF 请求方法有8种: GET、POST、DELETE、PUT、HEAD、TRACE、CONNECT 、OPTIONS,常用的是GET和POST
- GET:请求获取Request-URI所标识的资源
- POST:在Request-URI所标识的资源后附加新的数据
- HEAD:请求获取由Request-URI所标识的资源的响应消息报头
- PUT: 请求服务器存储一个资源,并用Request-URI作为其标识
- DELETE :请求服务器删除Request-URI所标识的资源
- TRACE : 请求服务器回送收到的请求信息,主要用于测试或诊断
- CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
- OPTIONS :请求查询服务器的性能,或者查询与资源相关的选项和需求
HTTP相应报文:
-
状态行: HTTP-Version State-Code Reason-Phrase CRLF
- 状态码值:
- 100~199:指示信息,表示请求已接收,继续处理
- 200~299:请求成功,表示请求已被成功接收、理解、接受
- 300~399:重定向,要完成请求必须进行更进一步的操作
- 400~499:客户端错误,请求有语法错误或请求无法实现
- 500~599:服务器端错误,服务器未能实现合法的请求
- 常用的值
- 200 OK:客户端请求成功
- 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden:服务器收到请求,但是拒绝提供服务
- 500 Internal Server Error:服务器发生不可预期的错误
- 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常
- 消息报头
- 空行
- 响应正文
HTTP消息报头:由key-value组成,每行一对,用:分隔
-
通用报头: 可以出现在请求报头,也可以出现在响应报头中
- Date:表示消息产生的日期和时间
- Connection:允许发送指定连接的选项,例如指定连接是连续的,或者指定“close”选项,通知服务器,在响应完成后,关闭连接
- Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)
-
请求报头
- Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
- User-Agent:发送请求的浏览器类型、操作系统等信息
- Accept:客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
- Accept-Encoding:客户端可识别的数据编码
- Accept-Language:表示浏览器所支持的语言类型
- Connection:允许客户端和服务器指定与请求/响应连接有关的选项,例如这是为Keep-Alive则表示保持连接。
- Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
-
响应报头
- Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
- Server:包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的
-
实体报头: 可以出现在请求报头,也可以出现在响应报头中
- Content-Type:发送给接收者的实体正文的媒体类型
- Content-Lenght:实体正文的长度
- Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
- Content-Encoding:实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
- Last-Modified:实体报头用于指示资源的最后修改日期和时间
- Expires:实体报头给出响应过期的日期和时间
HttpClient和HttpURLConnection
Android SDK中包含HttpClient,但在android6.0及更新版本删除了HttpClient类库,添加支持在对于module的build文件android标签下添加useLibrary 'org.apache.http.legacy'
OKHttp3
在RealCall类中AsyncCall方法通过添加5个默认拦截器,完成一个请求,获取数据
RealInterceptorChain类中proceed方法
通过一步步次序的调用拦截器,每个拦截器都会调用该proceed方法,并且index+1继续调用下一个拦截器,直到CallServerInterceptor类
封装并返回最后的数据。每个拦截器的功能都不一样,添加了默认值并执行了一些操作。根据名称可以大概判断拦截器的功能,具体实现查看源码。
OKHttpClient类通过Dispatcher任务调度来控制并发请求,设置了很多默认变量,创建okhttpclient时我们可以自定义这些值