一、iOS9 网络编程的重大改变:
1、网络请求方式的改变
1)NSURLConnection: iOS9之前使用
2)NSURLSession: iOS9 使用这个类
2、后台服务器传输协议由HTTP改成HTTPS
1)iOS开发 -> info.plist -> App Transport Security Settings ->Allow Arbitrary Loads -> YES
I
二、URL:
1、概念:
Uniform Resource Locator 统一资源定位符
2、结构
1、URL包含模式(或称协议)、服务器名称(或IP地址)、 路径和文件名
https :// www.baidu.com /img/bd_logo1.png
可以通过URL找到 服务器中的文件
URL中如果包含中文:
NSString *s = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
练习:通过连接加载图片
三、HTTP:
1、全称
Hypertext Transfer Protocol 超文本传输协议
https——用安全套接字层 传送的超文本传输协议
2、概念:
超文本传输协议是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种 发布和接收 HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基
是用于从WWW服务器传输超文本到本地浏览器的传输协议
3、通讯流程
1)首先客户端发送一个请求(request)给服务器
request由两部分组成:
请求头
请求体
2)服务器在接收到这个请求后将生成一个响应(response)返回给客户端
response由两部分组成:
相应头
相应体
4、常用请求方法
1) get 一般上请求数据时使用,直接将参数暴漏到url中,参数的长度有限制
2) post 一般上传数据时使用,将敏感的参数放到请求体中,在url中看不到,POST传递的数据量没有限制(具体还得看服务器的处理能力)
PS:get post的选择
1)如果要传递大量数据 比如文件上传 只能用POST请求
2)GET的安全性比POST要差些 如果包含机密\敏感信息 建议用POST
3)如果仅仅是索取数据(数据查询) 建议使用GET
4)如果是增加、修改、删除数据 建议使用POST
5、发送了一个请求 没有任何回应
1)没联网
2)请求内容错误:URL
练习:通过浏览器了解HTTP请求过程
四、JSON和XML
1、基本概念
查看博客 http://www.jianshu.com/p/5df890302416
2、JSON解析
[NSJSONSerialization JSONObjectWithData:nil options:NSJSONReadingMutableContainers error:nil];
NSJSONReadingMutableContainers:返回可变容器,NSMutableDictionary或NSMutableArray。
NSJSONReadingMutableLeaves:返回的JSON对象中字符串的值为NSMutableString,
NSJSONReadingAllowFragments:允许JSON字符串最外层既不是NSArray也不是NSDictionary,但必须是有效的JSON Fragment。例如使用这个选项可以解析 @“123” 这样的字符串
3、XML解析
1)准备工作
将GDataXMLNode文件加入至工程中
向Frameworks文件中添加libxml2.dylib库
在Croups & Files 侧边栏中双击工程图标,找到 build setting修改两个属性:
Search Paths中 找到Header Search Paths 将其对应的值修改为:/usr/include/libxml2,
在Linking中找到 Other Linker Flags 对应的值改为:-lxml2。
2) 读取xml文件
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:data error:nil];
3)获取到根节点
GDataXMLElement *rootElement = [document rootElement];
4)取出节点的属性值
[element attributeForName:@"id"]
4)根据节点取值
[rootElement elementsForName:@"from"]
练习:自己写JSON和XML串并解析
五、iOS下的HTTP请求过程
1、准备request
1)概念
iOS下使用NSURLRequest或者NSMutableURLRequest对象作为request,后者可以添加请求头
在请求中需要两个基本元素:
要加载的URL
加载的方式(默认是get)
如果需要,可以采用如下方式添加请求头、请求体
[request addValue:nil forHTTPHeaderField:nil]; //可变请求对象,才设置请求头
request.HTTPBody //请求体
2)request的缓存策略问题
不考虑缓存策略
+ (instancetype)requestWithURL:(NSURL *)URL;
- (instancetype)initWithURL:(NSURL *)URL
考虑缓存策略 超时限制
+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval
缓存策略的不同
默认的缓存策略 如果缓存不存在 直接从服务端获取 如果缓存存在 会根据response中的Cache-Control字段判断下一步操作
NSURLRequestUseProtocolCachePolicy,
忽略缓存 重新请求
NSURLRequestReloadIgnoringCacheData
有缓存就使用 不管其有效性 没有缓存就重新请求
NSURLRequestReturnCacheDataElseLoad
有缓存就用缓存 没有缓存就不发请求 当做请求出错处理(用于离线模式)
NSURLRequestReturnCacheDataDontLoad
3)缓存策略的选择,如果请求某个URL的返回数据
经常更新:不能用缓存 比如股票、彩票数据
一成不变:果断用缓存
偶尔更新:可以定期更改缓存策略 或者 清除缓存
提示:如果大量使用缓存 会越积越大 建议定期清除缓存
2、使用NSURLSession发送请求
1)创建一个NSURLSession对象,来帮助发送request请求
//数据请求,返回的是一个NSURLSessionDataTask对象,专门用来做数据类的网络请求任务
[session dataTaskWithRequest:nil completionHandler:nil];
//上传请求,返回的是一个NSURLSessionUploadTask对象,专门用来做上传类的网络请求任务
[session uploadTaskWithRequest:nil fromData:nil completionHandler:nil];
//下载请求,返回的是一个NSURLSessionDownloadTask对象,专门用来做下载类的网络请求任务
[session downloadTaskWithRequest:nil completionHandler:nil];
2)开始请求
[sessionTask resume];
3、获取响应头和相应体信息
//获取到相应头
NSHTTPURLResponse *httpResopnse = (NSHTTPURLResponse *)response;
//获取响应体
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
六:网络环境判断
Reachability
(1)导入类名
(2)创建对象 hostName尽量用一个稳定的网络
(3)添加观察者 接收网络环境发生改变的通知 通知的名字 kReachabilityChangedNotification
(4)开始检测
(5)在通知中得到 Reachability对象 not.object 获得网络环境的状态
二、网络下载文件
1、小文件下载使用block方式,不能监听下载进度
1)准备request
NSString *path = [NSString stringWithFormat:
path = [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString:path];
NSMutableURLRequest *reuqest = [NSMutableURLRequest requestWithURL:url];
2) 准备发送请求的NSURLSession对象
NSURLSession *session = [NSURLSession sharedSession];
3)发送请求并获得NSURLSessionDownloadTask对象,采用block方式
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:reuqest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString *documentPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
NSFileManager *fileMange = [NSFileManager defaultManager];
NSData *data = [NSData dataWithContentsOfFile:[location path]];
[fileMange createFileAtPath:documentPath contents:data attributes:nil];
NSLog(@"%@",documentPath);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@"%@",httpResponse.allHeaderFields);
}];
4)开始请求
[downloadTask resume];
2、大文件采用代理方式,能够监听下载进度
1)准备request
NSURL *url = [NSURL URLWithString:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
2)获取到发送请求的NSURLSession对象,并设置会话模式、代理(记得遵守下载的协议)、线程队列
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
PS:三种会话方式
进程内会话(默认会话),用硬盘来缓存数据。
defaultSessionConfiguration
临时的进程内会话(内存),不会将cookie、缓存储存到本地,只会放到内存中,当应用程序退出后数据也会消失
ephemeralSessionConfiguration
后台会话,相比默认会话,该会话会在后台开启一个线程进行网络数据处理
backgroundSessionConfiguration
3)获取到NSURLSessionDownloadTask对象,不需要用block
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
4) 实现代理方法
//下载完成时调用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSLog(@"finished=%@",NSHomeDirectory());
}
//下载过程中调用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
//参数分别是
当前这次下载的数据
已经下载的总数据
期待下载的总数据
NSLog(@"%lld %lld %lld",bytesWritten,totalBytesWritten,totalBytesExpectedToWrite);
NSLog(@"%@",[NSThread currentThread]);
}
5)下载控制
//开始(恢复)下载
[downloadTask resume];
//挂起下载
[downloadTask suspend];
//取消下载
[downloadTask cancel];
OSI网络通讯协议模型,是一个参考模型,参考于他的TCP/IP协议才是目前网络上通用的网络通讯协议,接下来先了解一下TCP/IP协议。
通常所说的TCP/IP协议,其实是一个协议集合,这个集合里面包含了网络通讯所需的所有协议,里面不仅有TCP(传输控制协议)、IP(网际协议),还有UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP、TFTP等许多协议,但因为TCP协议和IP协议是保证数据完整传输的两个基本的重要协议,所以该协议集合就被命名为TCP/IP协议了。
TCP/IP协议的制定是参考于OSI模型的,但并没有严格按照OSI规定的七层去划分,而是划分了四层,
应用层
传输层
网络层
网络接口层
OSI和TCP/IP对比图
目前我们已经知道TCP/IP协议分为四个层次,我举个例子简单说明一下各个层的作用,拿寄送邮件举例,A寄邮件给B,A关心的是用什么格式写什么内容给B(应用层内容),是寄挂号信(信件丢失会赔偿)还是寄平信(信件丢失不赔偿)(应用层内容),A是不会关注邮件传送过程中采用了哪条路线,邮递员是如何把信地道B手里的(网络层,网络接口层)。接下来再详细讲一下应用层和传输层。
传输层 传输层有多个协议,但最主要的是TCP和UDP协议。两者的区别在与TCP协议需要接收方反馈,传输更可靠,而UDP协议虽然不需要反馈,但传输的速率比较高。,至于具体采用哪种方式,需要具体问题具体分析,在不可靠的网络传送过程中一般选择TCP传送方式,在讲求效率或者不在乎传输失误的情况下可以选择UDP方式来提高传输速率。
应用层 应用层协议有很多,每一个协议代表一种类型的服务。
HTTP协议,万维网服务
FTP协议,文件传送服务
POP3协议,邮件服务
二、利用Socket建立网络连接的步骤
建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。
而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
三、HTTP链接的特点
HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
四、TCP和UDP的区别(考得最多。。快被考烂了我觉得- -\\)
1、TCP是面向链接的,虽然说网络的不安全不稳定特性决定了多少次握手都不能保证连接的可靠性,但TCP的三次握手在最低限度上(实际上也很大程度上保证了)保证了连接的可靠性;
而UDP不是面向连接的,UDP传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,当然也不用重发,所以说UDP是无连接的、不可靠的一种数据传输协议。
2、也正由于1所说的特点,使得UDP的开销更小数据传输速率更高,因为不必进行收发数据的确认,所以UDP的实时性更好。
知道了TCP和UDP的区别,就不难理解为何采用TCP传输协议的MSN比采用UDP的QQ传输文件慢了,但并不能说QQ的通信是不安全的,
因为程序员可以手动对UDP的数据收发进行验证,比如发送方对每个数据包进行编号然后由接收方进行验证啊什么的,
即使是这样,UDP因为在底层协议的封装上没有采用类似TCP的“三次握手”而实现了TCP所无法达到的传输效率。