一、http 理论基础

本次分享是的okHttp的源码分析,说起okhttp,相信大家都会用了,可以说是现在java与android最流行的网络框架库,而在一些面试过程中,面试官也总是喜欢问http,tcp,udp协议之类。再问是否了解过okhttp,内部实现什么的,而身为android开发者,我们是属于应用层开发,对http底层协议了解也是有必要的。这是背景。本次文章分为两个部分,一是讲下http理论基础,二部分才是分析okhttp源码,大家都知道okhttp既然是http网络库,了解http理论的知识还是很有必要的。ok,话不多说,进入正文

一、OSI 参考模型与TCP/IP五层模型

1、OSI的来源
        OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网络互连模型
        ISO为了更好的使网络应用更为普及,推出了OSI参考模型。其含义就是推荐所有公司使用这个规范来控制网络。这样所有公司都有相同的规范,就能互联了。
    TCP/IP五层协议和OSI的七层协议对应关系如下。

 

在每一层实现的协议也各不同,即每一层的服务也不同.下图列出了每层主要的协议。

以上图片出自 OSI七层模型与TCP/IP五层模型https://www.cnblogs.com/qishui/p/5428938.html

好的,上面两张图的左边OSI参考模型与TCP/IP五层模型相信大家无论在学计算机网络时还是其它文章,都见到过很多次,这部分可以说是计算机网络最枯燥的地方,纯理论,看不见摸不着,这里个人总结一下(个人理解,可能有误):OSI只是参考模型,让所有公司都这样协议,这样大家都能通信了,而实际常用的TCP/IP协议,所以有TCP/IP五层模型,区别就是让 会话层、表示层、应用层统归于应用层,而这里我们最少需要了解的是:传输层的TCP、UDP的区别

二、传输层的TCP、UDP的区别

什么是TCP

TCP(Transmission Control Protocol传输控制协议)是一种面向连接的,可靠的,基于字节流的传输通信协议。
1、面向连接,即在客户端和服务器之间发送数据之间,必须先建立连接
2、连接需要建立三次握手、四次挥手断开连接
3、传输数据时可靠的

TCP连接建立——使用三次握手建立连接

1、客户端发送请求【寻址请求】
2、服务器端收到报文请求,回应客户端【确认请求】
3、客户端收到服务端的报文进行回应。【连接请求】
三次握手完成,TCP客户端和服务端成功地建立连接,可以传输数据。

当然上面只是正常的流程,有很多特殊情况在里面需要处理,如dos攻击就是客户端发起请求,却不回应服务端的请求,导致服务器连接一直没有建立,占用了等待池连接,导致正常用户无法连接。

TCP终止一个连接——四次挥手

æ­å¼è¿æ¥ç¶ææ¶åºå¾

1、客户端发起断开请求
2、服务端收到断开请求并回复客户端,至此,客户端不可以再往服务端传输数据,但服务端还可以发送数据。
3、服务端数据发送完毕,发起断开请求
4、客户端收到断开请求并回复服务端,至此,连接真正断开。

注意:这里的首次结束请求可以是任意一端先发起的,这里以客户端发起为例。
这样整个连接就关闭了,当然上面只是正常的状态,也有很多非正常的状态。如客户端发起断开后就不管了,服务器发起断开请求一直等不到回应,解决办法有等待超时之类。
而且在三次握手建立连接后传输数据可以是任意多次,所以常说的长连接实际就是Tcp连接。

小结

TCP 为了数据能正常发送,还做了滑动窗口,拥塞控制,失败重传等机制来保证数据的发送与完整性,这里不展示详细说明,参考其它文献。

而UDP相对就简单许多,没有三次连接与四次挥手,传输不可靠,服务端只管发送,不管客户端有没有收到,适合数据及时性高对部分数据丢包能忍受的场景。对于应用来说有直播类与语音视频通话类应用,TCP的应用就要广一些,像DNS,SMTP邮箱,FTP文件服务,当然还有HTTP。

参考文章:TCP 和 UDP 的区别 :https://blog.youkuaiyun.com/zhang6223284/article/details/81414149

三、应用层 HTTP 

前面的知识讲的比较简,因为这篇主角是http,所以这里讲的会比较多。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议。
上面说到Http是基于tcp的,http是一种 (请求响应式) 协议 。
请求响应式是指建立连接后数据只发送和接收各一次,即

连接建立---->客户端发送数据---->服务端收到处理
   |                              |
下一次请求                          V
   |                              |
连接关闭--<--客户端收到数据----<----<|

这里用简图表示,每次请求都会发起连接,所以是无状态的,服务器不用保存连接状态,数据发送后就释放资源,减少压力,但是如果一些场景中如登录状态,这时就只能每次都要发送一个登录后的状态key,放在cookie 中,这是HTTP/1.0的协议,而HTTP/1.1与更高已经可以在连接中多次发送与接收数据了。

HTTP 请求方法

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。而实际上常用的还是GET与POST,故本篇也只介绍get与Post

GET请求指定的页面信息,并返回实体主体。
POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。

而get与post 的区别大概是get 的传输数据在拼接在地址中的,以?开头,然后key=value,如有多个 以 "& "拼接,可传数据较少,(不同浏览器不一样,大约32k)而且相对明文,适合拉取数据。而Post 是有请求体的,数据大小没有限制,适合上传数据。

HTTP 消息结构

1、客户端请求消息

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。

post 举例

POST /hello.txt HTTP/1.1  请求行
Host: www.example.com //请求头start--
Accept-Language: en, mi
Content-Length: 23
Cookie: key=value; key2=value2  
User-Agent: okhttp/3.10        //请求头end---
                       //如果有请求体的话,空行是必须的,空行后是body
key=value&key2=value2  //请求体body

上面就是一个post请求的数据,只要建立一个tcp连接后,然后发送上面格式数据,就可以完成一个http请求,后面会讲实例。

2、服务器响应消息

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

HTTP状态码

当一个http请求发出后,服务器会返回一个包含HTTP状态码的信息头(server header)用以响应客户端的请求。
下面是常见的HTTP状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

HTTP状态码分类
分类分类描述
1**信息,服务器收到请求,需要请求者继续执行操作
2**成功,操作被成功接收并处理
3**重定向,需要进一步的操作以完成请求
4**客户端错误,请求包含语法错误或无法完成请求
5**服务器错误,服务器在处理请求的过程中发生了错误

Header体中几种常用head

Content-Type

内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和编码,决定客户端将以什么形式、什么编码读取这个文件,这就是经常看到一些网页点击的结果却是下载到的一个文件或一张图片的原因。

文件扩展名Content-Type(Mime-Type)
.jpgimage/jpeg
.xmltext/xml
.jsonapplication/json
.txtapplication/x-www-form-urlencoded

 

这里只列了几种,实际上非常多,而且可以自定义扩展 application/xxx ,只要你的程序能支持指定编解码的话,就可以。

Content-Length

数据长度,一般为body请求体的长度,用于服务器解析数据用,如果你的body实际长为100,而content-length却只有10,那么服务器只会取前10的数据。

Cookie

cookie 是基于站点的,同一站点,客户端会发送相同的cookie,保存在客户端,但是设置却是在服务端,单个站点最大保存20个,每个不超过4kb。
前面说了,http无状态,如果服务器有一些状态需要客户端在下次请求中上传,那么可以放在Cookie中,一般是服务器返回head中为 Set-Cookie: key=value; key2=value2 ,然后客户发现这个的head,将于下次请求携带到head中  cookie: key=value; key2=value2 ,这样服务端就知道这个用户是刚才那个用户了。不过现代的cookie 有点被滥用了。最被常用来跟踪用户,然后推送个性广告,详细见其它文献。和这个当处设计的用途不太相符,所以现代浏览器都会有禁用cookie 跟踪之类的开关。提醒下,默认的okhttp是禁用cookie 的,需要你自己实现保存与添加。

四、本篇总结

ok、至此,我们已经简单复习了一遍学习http。当然每一个知识点都没有讲的很细,因为每一个都能写一大篇,而我这是站在一个应用层开发者来看的。而且部分是参考其它文献的。

希望你最少能了解:
1、tcp、udp的区别
2、http是基于tcp的,http常用的get,post 的区别
3、http请求的消息结构,由请求行、请求头、请求体组成
4、常见的http协议code
5、content-Type 与content-Length

这些都是看okhttp所具备的理论知识,并不说不懂这些就看不懂源码,而是如果你能理解这些的话,后面分析与在看okhttp源码的时候会轻松许多。

 

参考文献:  OSI七层模型与TCP/IP五层模型TCP 和 UDP 的区别 HTTP 简介

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值