Android网络编程(一)HTTP协议原理
相关文章
Android网络编程(一)HTTP协议原理
Android网络编程(二)HttpClient与HttpURLConnection
Android网络编程(三)Volley使用方法全解析
Android网络编程(四)从源代码解析volley
Android网络编程(五)OkHttp2.x使用方法全解析
Android网络编程(六)OkHttp3使用方法全解析
Android网络编程(七)源代码解析OkHttp前篇[请求网络]
Android网络编程(八)源代码解析OkHttp后篇[复用连接池]
Android网络编程(九)Retrofit2前篇[基本使用]
Android网络编程(十)Retrofit2后篇[注解]
Android网络编程(十一)源代码解析Retrofit
前言
这篇文章是这个系列的开篇,作为移动开发人员,开发的应用不免会对网络进行訪问。尽管如今已经有非常多的开源库帮助我们能够轻而易举的訪问网络,可是我们仍要去了解网络訪问的原理,这也是一个优秀开发人员所必备的知识点。这篇文章我们就先来了解一下HTTP协议原理。
1.HTTP简单介绍
HTTP是一个属于应用层的面向对象的协议,因为其简捷、高速的方式。适用于分布式超媒体信息系统。
它于1990年提出,经过几年的使用与发展。得到不断地完好和扩展。
HTTP协议的主要特点
- 支持C/S(客户/server)模式。
- 简单高速:客户向server请求服务时,仅仅需传送请求方法和路径。
请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与server联系的类型不同。因为HTTP协议简单,使得HTTPserver的程序规模小,因而通信速度非常快。
- 灵活:HTTP同意传输随意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接仅仅处理一个请求。server处理完客户的请求。并收到客户的应答后,即断开连接。
採用这样的方式能够节省传输时间。
- 无状态:HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力。缺少状态意味着假设兴许处理须要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
还有一方面,在server不须要先前信息时它的应答就较快。
HTTP URL 的格式例如以下
http://host[":"port][abs_path]
http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址。port指定一个端口号,为空则使用默认端口80。abs_path指定请求资源的URI(Web上随意的可用资源)。
HTTP有两种报文各自是请求报文和响应报文。让我们先来看看请求报文。
2.HTTP的请求报文
先来看看请求报文的一般格式:
通常来说一个HTTP请求报文由请求行、请求报头、空行、和请求数据4个部分组成。
请求行
请求行由请求方法,URL字段和HTTP协议的版本号组成。格式例如以下:
Method Request-URI HTTP-Version CRLF
当中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本号;CRLF表示回车和换行(除了作为结尾的CRLF外,不同意出现单独的CR或LF字符)。
HTTP请求方法有8种。各自是GET、POST、DELETE、PUT、HEAD、TRACE、CONNECT 、OPTIONS。当中PUT、DELETE、POST、GET分别相应着增删改查。对于移动开发最经常使用的就是POST和GET了。
- GET:请求获取Request-URI所标识的资源
- POST:在Request-URI所标识的资源后附加新的数据
- HEAD:请求获取由Request-URI所标识的资源的响应消息报头
- PUT: 请求server存储一个资源。并用Request-URI作为其标识
- DELETE :请求server删除Request-URI所标识的资源
- TRACE : 请求server回送收到的请求信息。主要用于測试或诊断
- CONNECT: HTTP/1.1协议中预留给能够将连接改为管道方式的代理server。
- OPTIONS :请求查询server的性能。或者查询与资源相关的选项和需求
比如我去訪问我的CSDN博客地址请求行是:
GET http://blog.csdn.net/itachi85 HTTP/1.1
请求报头
在请求行之后会有0个或者多个请求报头,每一个请求报头都包括一个名字和一个值,它们之间用“:”切割。请求头部会以一个空行,发送回车符和换行符,通知server以下不会有请求头。关于请求报头,会在后面的消息报头一节做统一的解释。
请求数据
请求数据不在GET方法中使用。而是在POST方法中使用。
POST方法适用于须要客户填写表单的场合,与请求数据相关的最经常使用的请求头是Content-Type和Content-Length。
3.HTTP的响应报文
先来看看响应报文的一般格式:
HTTP的响应报文由状态行、消息报头、空行、响应正文组成。
响应报头后面会讲到,响应正文是server返回的资源的内容,先来看看状态行。
状态行
1、状态行格式例如以下:
HTTP-Version Status-Code Reason-Phrase CRLF
当中,HTTP-Version表示serverHTTP协议的版本号。Status-Code表示server发回的响应状态代码。Reason-Phrase表示状态代码的文本描写叙述。
状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
- 100~199:指示信息,表示请求已接收,继续处理
- 200~299:请求成功。表示请求已被成功接收、理解、接受
- 300~399:重定向,要完毕请求必须进行更进一步的操作
- 400~499:client错误。请求有语法错误或请求无法实现
- 500~599:server端错误,server未能实现合法的请求
常见的状态码例如以下:
- 200 OK:client请求成功
- 400 Bad Request:client请求有语法错误,不能被server所理解
- 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden:server收到请求。可是拒绝提供服务
- 500 Internal Server Error:server发生不可预期的错误
- 503 Server Unavailable:server当前不能处理client的请求。一段时间后可能恢复正常
比如訪问我的CSDN博客地址响应的状态行是:
HTTP/1.1 200 OK
4.HTTP的消息报头
消息报头分为通用报头、请求报头、响应报头、实体报头等。消息头由键值对组成,每行一对。关键字和值用英文冒号“:”分隔。
通用报头
既能够出如今请求报头,也能够出如今响应报头中
- Date:表示消息产生的日期和时间
- Connection:同意发送指定连接的选项。比如指定连接是连续的。或者指定“close”选项,通知server,在响应完毕后,关闭连接
- Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现)。且是独立的(一个消息的缓存指令不会影响还有一个消息处理的缓存机制)
请求报头
请求报头通知server关于client求求的信息,典型的请求头有:
- Host:请求的主机名,同意多个域名同处一个IP地址,即虚拟主机
- User-Agent:发送请求的浏览器类型、操作系统等信息
- Accept:client可识别的内容类型列表,用于指定client接收那些类型的信息
- Accept-Encoding:client可识别的数据编码
- Accept-Language:表示浏览器所支持的语言类型
- Connection:同意client和server指定与请求/响应连接有关的选项,比如这是为Keep-Alive则表示保持连接。
- Transfer-Encoding:告知接收端为了保证报文的可靠传输。对报文採用了什么编码方式。
响应报头
用于server传递自身信息的响应,常见的响应报头:
- Location:用于重定向接受者到一个新的位置,经常使用在更换域名的时候
- Server:包括可server用来处理请求的系统信息。与User-Agent请求报头是相相应的
实体报头
实体报头用来定于被传送资源的信息,既能够用于请求也可用于响应。请求和响应消息都能够传送一个实体。常见的实体报头为:
- Content-Type:发送给接收者的实体正文的媒体类型
- Content-Lenght:实体正文的长度
- Content-Language:描写叙述资源所用的自然语言,没有设置则该选项则觉得实体内容将提供给全部的语言阅读
- Content-Encoding:实体报头被用作媒体类型的修饰符。它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须採用相应的解码机制。
- Last-Modified:实体报头用于指示资源的最后改动日期和时间
- Expires:实体报头给出响应过期的日期和时间
5.应用举例
要想查看网页或者手机请求网络的请求报文和响应报文有非常多种方法,这里推荐採用Fiddler,在Android利用Fiddler进行网络数据抓包这篇文章中详尽介绍了怎样使用Fiddler。在这里就不赘述了。
打开Fiddler,然后用浏览器訪问我的CSDN博客站点:
点击红色画笔的区域就能够看到请求报文和响应报文了
请求报文:
GET http://blog.csdn.net/itachi85 HTTP/1.1 //请求行
Host: blog.csdn.net //请求报头
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 QQBrowser/9.3.6872.400
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: bdshare_firstime=1443768140949; uuid_tt_dd=5028529250430960147_20151002;
...省略
非常easy看出訪问的是我的博客地址http://blog.csdn.net/itachi85,请求的方法是GET,因为是GET方法所以并没有请求数据。
响应报文:
HTTP/1.1 200 OK //状态行
Server: openresty //响应报头
Date: Sun, 27 Mar 2016 08:26:54 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept-Encoding
Cache-Control: private
X-Powered-By: PHP 5.4.28
Content-Encoding: gzip
//不能省略的空格
28b5
}ysI 1ߡFsgl n- ]{^_ { 'z! C , m# 0 !l ` 4x ly .ݪ*
ڴzAt_Xl * 9'O ɬ ' ק 3 ^1a
...省略
响应报文没什么可说的,接下来我们配置好手机网络代理,訪问一个应用的界面
请求报文:
POST http://patientapi.shoujikanbing.com/api/common/getVersion HTTP/1.1 //请求行
Content-Length: 226 //请求报头
Content-Type: application/x-www-form-urlencoded
Host: patientapi.shoujikanbing.com
Connection: Keep-Alive
User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; MI NOTE LTE Build/KTU84P) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
Accept-Encoding: gzip
//不能省略的空格,以下是请求数据
clientversion=2_2.0.0&time=1459069342&appId=android&channel=hjwang&sessionId=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9&token=b191944d680145b5ed97f2f4ccf03058&deviceId=869436020220717&type=2&version=2.0.0
从请求报文的请求行来看,请求的方法是POST,请求地址为http://patientapi.shoujikanbing.com/api/common/getVersion。非常显然是获取版本号信息的接口。
响应报文:
HTTP/1.1 200 OK //状态行
Server: nginx //响应报头
Date: Sun, 27 Mar 2016 09:02:20 GMT
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: sessionId=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9; expires=Mon, 28-Mar-2016 09:02:20 GMT; Max-Age=86400; path=/; domain=.shoujikanbing.com
Set-Cookie: PHPSESSID=0d1cee1f31926ffa8894c64804efa855101d56eb21caf5db5dcb9a4955b7fbc9; path=/; domain=.shoujikanbing.com
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip
//不能省略的空格
17f //实体报文编码格式为gzip所以显示在这里的响应数据是乱码
mP N @ "E ?
n m 1
w ( HL (1^ P nK E ѷ93'3gNLH 7P $c \ T 4a6 L:+ 1dY%$g h H +
...省略
响应报文的实体採用的编码格式为为gzip,所以在Fiddler软件中显示的是乱码。
欢迎关注我的微信公众号。第一时间获得博客更新提醒。以及很多其它成体系的Android相关原创技术干货。
扫一扫下方二维码或者长按识别二维码,就可以关注。
Android网络编程(一)HTTP协议原理的更多相关文章
- Android网络编程系列 一 TCP/IP协议族
在学习和使用Android网路编程时,我们接触的仅仅是上层协议和接口如Apache的httpclient或者Android自带的httpURlconnection等等.对于这些接口的底层实现我们也有必 ...
- Android网络编程要学的东西与Http协议学习
本节引言: 本节开始我们来学习Android网络编程相关的一些东西:Android端网络编程是要干嘛?http协议的学习,使用自带扣脚Json解析类解析Json,XML解析常用的几种方式,HttpUr ...
- Android网络编程系列 一 Socket抽象层
在<Android网络编程>系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽 ...
- 【Android 应用开发】Android 网络编程 API笔记 - java.net 包 权限 地址 套接字 相关类 简介
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- Android 网络编程 API笔记 - java.net 包 权限 地址 套接字 相关类 简介
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- Android 网络编程 记录
简单介绍 看了深入理解Android网络编程感觉不错.今天对Android网络编程进行了要点记录. 内容 Android基于网络技术和编程实践 要点 定义 描写叙述 IP协议 用于报文交换网络的一种面 ...
- Android网络编程(三)Volley使用方法全解析
相关文章 Android网络编程(一)HTTP协议原理 Android网络编程(二)HttpClient与HttpURLConnection 前言 Volley想必许多人都用过,为了建立网络编程的知识 ...
- Android网络编程(十)Retrofit2后篇[注解]
G相关文章 Android网络编程(一)HTTP协议原理 Android网络编程(二)HttpClient与HttpURLConnection Android网络编程(三)Volley用法全解析 An ...
- Android网络编程概述
Android网络编程概述 首先,应该了解的几个问题: 1)Android平台网络相关API接口 a) java.net.*(标准Java接口) java.net.*提供与联网有关的类,包括流.数据包 ...
随机推荐
- ubuntu声音问题
在终端查看声卡: aplay -l 成功显示: **** PLAYBACK硬件设备列表 **** card 0: Intel [HDA Intel], device 0: ALC662 rev1 An ...
- Eclipse SDK Android Studio 下载地址
https://developer.android.com/sdk/index.html#download 这个网址可以下载需要的东西,FQ的话可以给 xifulinmen@gmail.com 发一个 ...
- c#录音和放音,超简单!不用DirectX
最近在做android与C#录音并互相通信的小东西.但是卡在C#录音这儿了.找了好久,说的都是DirectX,可是我总是安装不上,这才找到了这个简单的录音方法.当然,如果你想要录得好并且处理音频,那还 ...
- 显卡、显卡驱动、CUDA、cuDNN之间的关系
作者:冬瓜哥链接:https://www.zhihu.com/question/59184480/answer/166167659来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- 深入理解VMware虚拟机网络通信原理
VMware虚拟机的上网方式有三种:NAT.桥接.仅主机模式,本篇介绍桥接模式和NAT模式. 1.实验环境 博主的实验环境如下: 宿主机操作系统:Windows 7 VMware Workstatio ...
- PO BO VO DTO POJO DAO概念及其作用(附转换图)
J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候,三分钟就被人家满口的专业术语喷晕了,PO VO BO DTO POJO DAO,一大堆的就来了(听过老罗对这种现象的批判的朋 ...
- nfd指令的详细说明
在eterm上执行NFD:SHAPEK/CA*OW指令,返回如下: LN CXR OW RT FBC/TC RBD MIN/MAX TRVDATE R 01 CA 450.00 U U 00D/00D ...
- asp.net网站发布
1.iis里面新建一个网站,目录可以新建(例如:F:\dotNetWeb),还可以创建子文件夹如:F:\dotNetWeb\my,网站路径是可以自己设置的,也可以使用IIS默认的网站. 2.vs201 ...
- Js计算指定日期加上多少天,加多少月,加多少年的日期
function DateAdd(interval,number,date) { /* * 功能:实现VBScript的DateAdd功能. * 参数:interval,字符串表达式,表示要添加的时间 ...
- WINDOWS 逻辑坐标 设备坐标 屏幕坐标 客户区坐标
转自:http://blog.csdn.net/lovesunshine2008/article/details/4048158 设置坐标映射 (1)Windows坐标系统 Windows坐标系 ...