iOS (二) - Http for iOS

随说 : 在网上有很多类似的文章,可以从网上获得更多的资料,真正做项目下来,网络请求是必不可小的,特别近期在做混编这一块,H5与objective-c的混编,抓取网页,分析网页数据展示,缓存,离线读取等.
HTTP协议是网络请求的基本协议,在项目中我们经常需要往服务端发POST或者GET请求,下面我将总结一下.

HTTP是什么?##

HTTP本质上是一种协议,全称是Hypertext Transfer Protocol,即超文本传输协议。从名字上可以看出该协议用于规定客户端与服务端之间的传输规则,所传输的内容不局限于文本(其实可以传输任意类型的数据)。
HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

iOS (二) - Http for iOS_第1张图片

Http请求是什么?##

你的app需要数据的时候,就需要去获取数据,问服务器拿数据就是通过发送请求以告诉服务器你想要什么,那么这里面包含的信息需要遵守Http的协议,统称为请求行

请求行###

请求行包含请求方法(Method)、请求统一资源标识符(URI)、HTTP版本号
例如请求百度的Logo图片

Method:GET URL:https://m.baidu.com/static/search/baiduapp_icon.png/ HTTP1.1
  1. 请求方法就是我们所熟悉的POST、GET、HEAD、PUT 查看请求方法大全
  2. URI就是URL中排除掉Host剩下的部分,也就是资源在服务器本地上的路径
  3. HTTP版本号,目前主流的版本是1.1(1999年开始采用),最新的版本是2.0(2015年5月发布)。不同版本之间差异下面会再展开

在IOS中 :
HTTP请求在iOS中用NSURLRequest与NSMutableRequest表示;HTTP响应用NSHTTPURLResponse表示。

请求头###

一个请求中含有的信息 : 下面是请求baidu

  1. Host: 目标服务器的网络地址
  2. Accept: 让服务端知道客户端所能接收的数据类型,如text/html /
  3. Content-Type: body中的数据类型,如application/json; charset=UTF-8
  4. Accept-Language: 客户端的语言环境,如zh-cn
  5. Accept-Encoding: 客户端支持的数据压缩格式,如gzip
  6. User-Agent: 客户端的软件环境,我们可以更改该字段为自己客户端的名字,比如百度
    User-Agent : Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1
  7. Connection: keep-alive,该字段是从HTTP1.1才开始有的,用来告诉服务端这是一个持久连接,“请服务端不要在发出响应后立即断开TCP连接”。关于该字段的更多解释将在后面的HTTP版本简介中展开。
  8. Content-Length: body的长度,如果body为空则该字段值为0。该字段一般在POST请求中才会有。
  9. Cookie: 记录者用户信息的保存在本地的用户数据,如果有会被自动附上

查看更多请求头信息

请求体###

真正需要发给服务端的数据,在使用POST-multipart上传请求中请求体就是上传文件的二进制NSData类型数据;在GET请求中请求体为空;在普通的POST请求中请求体就是一些表单数据。

NSURLRequest中提供请求体,只读

// 在NSURLRequest中, 该属性只能读取,所以不能通过setHTTPBody修改
@property (nullable, readonly, copy) NSData *HTTPBody;

@property (nullable, readonly, retain) NSInputStream *HTTPBodyStream;

NSMutableURLRequest中提供了几个属性标识Request中的请求体

// 在NSMutableURLRequest中, 该属性是是请求体的数据,可以通过setHTTPBody来设置请求体内容
@property (nullable, copy) NSData *HTTPBody;

@property (nullable, retain) NSInputStream *HTTPBodyStream;

IOS中对应请求的NSURLRequest类提供了什么方法

iOS (二) - Http for iOS_第2张图片
  1. 有两个类NSURLRequest与NSMutableRequest
  2. 其中NSURLRequest是继承 NSObject的 NSMutableRequest是继承NSURLRequest
  3. 另外NSURLRequest遵守协议

NSMutableRequest中提供了几个方法允许修改Request中的请求头

// 为请求头增加字段, field名字要严格遵守协议
- (void)addValue:(NSString *)value forHTTPHeaderField:(NSString *)field

// 根据field修改设置value, field要严格遵守http协议
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field

// 根据field的名字获取请求头的字段
- (nullable NSString *)valueForHTTPHeaderField:(NSString *)field;

// 还有一个属性, 存储该请求所有请求头信息
@property(copy) NSDictionary  *allHTTPHeaderFields

Http响应是什么?

响应与请求一样,客户端将请求发送到服务器后,服务器会根据请求的内容返回"内容",这个"内容"就叫做响应
响应由响应状态,响应头,响应实体组成

响应状态###

下面这个是典型的响应状态

HTTP/1.1 200 OK

查看更多响应状态

响应头###

响应头和请求头基本一样, 详细可以查看 查看更多响应头信息

响应实体###

请求体也是一样.

IOS中对应请求的NSURLResponse类提供了什么方法

iOS (二) - Http for iOS_第3张图片
// 只读 , 响应状态
@property (readonly) NSInteger statusCode;

// 只读 , 响应请求头
@property (readonly, copy) NSDictionary *allHeaderFields;

// 只读 , 响应对应的URL
@property (nullable, readonly, copy) NSURL *URL;

// 只读 , 响应对应的MIMEType, 关于这个类型不用死记,需要的时候再找
@property (nullable, readonly, copy) NSString *MIMEType;

注意,因为响应实体在IOS中转换为NSData,所以通过NSURLConnection(IOS9后调用NSURLSession)间接拿到response的数据,请求与响应之间建立的链接就是利用了NSURLConnection(NSURLSession)类

HTTP的请求与响应之间是如何连接的?##

HTTP 1.1(主流版本)###

HTTP 1.1(主流版本)比之前的版本多了几种新特性

  1. 增加请求头跟响应头,用于自定义整个链接过程中的一些行为
  2. 支持持久连接。客户端通过请求头中指定Connection为keep-alive告知服务端不要在完成响应后立即释放连接。HTTP是基于TCP的,在HTTP 1.1中一次TCP连接可以处理多次HTTP请求
  3. 客户端异步请求。打断请求与请求之间依赖关系,更好地利用资源,增加效率,有点类似多线程的异步处理。
iOS (二) - Http for iOS_第4张图片

由上图可以知道, 发送请求报文和接收响应报文,都必须在TCP已经成功连接的基础上进行的, 而HTTP 1.0版本中, 是没有持久连接的概念,也就是说以前是request - response 一次之后,TCP连接马上会断开. 下一次的request - response又会再次连接断开.持久连接很好地解决了这个问题.

几种概念的混淆(HTTP、Socket、TCP的区别)###

iOS (二) - Http for iOS_第5张图片
HTTP协议只是应用层的一个协议而尔,所以HTTP协议是基于TCP / IP的


先要知道的是TCP/IP是一个协议族,这是一套协议的集合, TCP/IP 是 OSI 七层协议的"封装"
而TCP只是 TCP/IP协议族中传输层的一个协议, 同一层中(传输层)中还有UDP协议


socket层只是在TCP/UDP传输层上做的一个抽象接口层,因此一个socket连接可以基于TCP,也有可能基于UDP。(TCP就是流式Socket, UDP就是数据报式Socket(SOCK_DGRAM))

区分好Http 与 Socket

  1. HTTP是短连接,尽管HTTP1.1开始支持持久连接,但仍无法保证始终连接。因为有超时的机制, 特定时间之后链接建立的链接即会超时, 超时之后TCP链接自动发送断开链接请求并且断开链接.
  2. HTTP采用“请求-响应”机制,在客户端还没发送消息给服务端前,服务端无法推送消息给客户端。必须满足客户端发送消息在前,服务端回复在后。,也就是说, "没请求,没交流"
  3. HTTP连接的是服务器与客户端之间的 点对多关系, 多个客户端对同一服务器发出请求, 然后服务器根据请求将相应返回给相应的客户端
  4. Socket(基于TCP协议的)是长连接,长连接的意思是指,连接时间长,Socket连接一旦建立TCP三次握手,除非一方主动断开,否则连接状态一直保持。
  5. Socket有两种模式,流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。基于TCP协议的socket连接同样需要通过三次握手建立连接,是可靠的;基于UDP协议的socket连接不需要建立连接的过程,不过对方能不能收到都会发送过去,是不可靠的,大多数的即时通讯IM都是后者。
  6. Socket连接的是更多就是点对点的关系了, Socket数据结构中包含这五种信息,(通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口), 所以更多的是一种 点对点的关系。

后记##

在IOS的体系中,建立Http连接的,一般用源生的NSURLConnection,(IOS7之后,用的NSURLSession),当然更多的是用AFNetWorking框架来发送请求
如果建立Socket连接,一般用CocoaAsyncSocket.
关于这两个大型框架的用法,后面我会贴出来在总结一下的.感谢查看


系列的其他整理

[IOS混合编程 - UIWebView 与 WKWebView . 基本使用 (一)][4]
[IOS混合编程 - Http for IOS (二)][5]
[IOS混合编程 - NSURLProtocol 的使用 (三)][6]
[4]: http://www.jianshu.com/p/b3e7fa514ab7
[5]: http://www.jianshu.com/p/a6830a9287d6
[6]: http://www.jianshu.com/p/ec5d6c204e17

你可能感兴趣的:(iOS (二) - Http for iOS)