一、iOS9 網(wǎng)絡(luò)編程的重大改變:
1、網(wǎng)絡(luò)請(qǐng)求方式的改變
1)NSURLConnection: iOS9之前使用
2)NSURLSession: iOS9 使用這個(gè)類
2、后臺(tái)服務(wù)器傳輸協(xié)議由HTTP改成HTTPS
1)iOS開發(fā) -> info.plist -> App Transport Security Settings ->Allow Arbitrary Loads -> YES
I
二、URL:
1、概念:
Uniform Resource Locator 統(tǒng)一資源定位符
2、結(jié)構(gòu)
1、URL包含模式(或稱協(xié)議)、服務(wù)器名稱(或IP地址)、 路徑和文件名
https ://? www.baidu.com? /img/bd_logo1.png
可以通過URL找到 服務(wù)器中的文件
URL中如果包含中文:
NSString *s = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
練習(xí):通過連接加載圖片
三、HTTP:
1、全稱
Hypertext Transfer Protocol 超文本傳輸協(xié)議
https——用安全套接字層 傳送的超文本傳輸協(xié)議
2、概念:
超文本傳輸協(xié)議是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。所有的WWW文件都必須遵守這個(gè)標(biāo)準(zhǔn)。設(shè)計(jì)HTTP最初的目的是為了提供一種 發(fā)布和接收 HTML頁(yè)面的方法。1960年美國(guó)人Ted Nelson構(gòu)思了一種通過計(jì)算機(jī)處理文本信息的方法,并稱之為超文本(hypertext),這成為了HTTP超文本傳輸協(xié)議標(biāo)準(zhǔn)架構(gòu)的發(fā)展根基
是用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議
3、通訊流程
1)首先客戶端發(fā)送一個(gè)請(qǐng)求(request)給服務(wù)器
request由兩部分組成:
請(qǐng)求頭
請(qǐng)求體
2)服務(wù)器在接收到這個(gè)請(qǐng)求后將生成一個(gè)響應(yīng)(response)返回給客戶端
response由兩部分組成:
相應(yīng)頭
相應(yīng)體
4、常用請(qǐng)求方法
1) get 一般上請(qǐng)求數(shù)據(jù)時(shí)使用,直接將參數(shù)暴漏到url中,參數(shù)的長(zhǎng)度有限制
2) post 一般上傳數(shù)據(jù)時(shí)使用,將敏感的參數(shù)放到請(qǐng)求體中,在url中看不到,POST傳遞的數(shù)據(jù)量沒有限制(具體還得看服務(wù)器的處理能力)
PS:get post的選擇
1)如果要傳遞大量數(shù)據(jù) 比如文件上傳 只能用POST請(qǐng)求
2)GET的安全性比POST要差些 如果包含機(jī)密\敏感信息 建議用POST
3)如果僅僅是索取數(shù)據(jù)(數(shù)據(jù)查詢) 建議使用GET
4)如果是增加、修改、刪除數(shù)據(jù) 建議使用POST
5、發(fā)送了一個(gè)請(qǐng)求 沒有任何回應(yīng)
1)沒聯(lián)網(wǎng)
2)請(qǐng)求內(nèi)容錯(cuò)誤:URL
練習(xí):通過瀏覽器了解HTTP請(qǐng)求過程
四、JSON和XML
1、基本概念
查看博客 http://www.itdecent.cn/p/5df890302416
2、JSON解析
[NSJSONSerialization JSONObjectWithData:nil options:NSJSONReadingMutableContainers error:nil];
NSJSONReadingMutableContainers:返回可變?nèi)萜鳎琋SMutableDictionary或NSMutableArray。
NSJSONReadingMutableLeaves:返回的JSON對(duì)象中字符串的值為NSMutableString,
NSJSONReadingAllowFragments:允許JSON字符串最外層既不是NSArray也不是NSDictionary,但必須是有效的JSON Fragment。例如使用這個(gè)選項(xiàng)可以解析 @“123” 這樣的字符串
3、XML解析
1)準(zhǔn)備工作
將GDataXMLNode文件加入至工程中
向Frameworks文件中添加libxml2.dylib庫(kù)
在Croups & Files 側(cè)邊欄中雙擊工程圖標(biāo),找到 build setting修改兩個(gè)屬性:
Search Paths中 找到Header Search Paths? 將其對(duì)應(yīng)的值修改為:/usr/include/libxml2,
在Linking中找到 Other Linker Flags 對(duì)應(yīng)的值改為:-lxml2。
2) 讀取xml文件
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:data error:nil];
3)獲取到根節(jié)點(diǎn)
GDataXMLElement *rootElement = [document rootElement];
4)取出節(jié)點(diǎn)的屬性值
[element attributeForName:@"id"]
4)根據(jù)節(jié)點(diǎn)取值
[rootElement elementsForName:@"from"]
練習(xí):自己寫JSON和XML串并解析
五、iOS下的HTTP請(qǐng)求過程
1、準(zhǔn)備request
1)概念
iOS下使用NSURLRequest或者NSMutableURLRequest對(duì)象作為request,后者可以添加請(qǐng)求頭
在請(qǐng)求中需要兩個(gè)基本元素:
要加載的URL
加載的方式(默認(rèn)是get)
如果需要,可以采用如下方式添加請(qǐng)求頭、請(qǐng)求體
[request addValue:nil forHTTPHeaderField:nil]; //可變請(qǐng)求對(duì)象,才設(shè)置請(qǐng)求頭
request.HTTPBody //請(qǐng)求體
2)request的緩存策略問題
不考慮緩存策略
+ (instancetype)requestWithURL:(NSURL *)URL;
- (instancetype)initWithURL:(NSURL *)URL
考慮緩存策略 超時(shí)限制
+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval
緩存策略的不同
默認(rèn)的緩存策略 如果緩存不存在 直接從服務(wù)端獲取 如果緩存存在 會(huì)根據(jù)response中的Cache-Control字段判斷下一步操作
NSURLRequestUseProtocolCachePolicy,
忽略緩存 重新請(qǐng)求
NSURLRequestReloadIgnoringCacheData
有緩存就使用 不管其有效性 沒有緩存就重新請(qǐng)求
NSURLRequestReturnCacheDataElseLoad
有緩存就用緩存 沒有緩存就不發(fā)請(qǐng)求 當(dāng)做請(qǐng)求出錯(cuò)處理(用于離線模式)
NSURLRequestReturnCacheDataDontLoad
3)緩存策略的選擇,如果請(qǐng)求某個(gè)URL的返回?cái)?shù)據(jù)
經(jīng)常更新:不能用緩存 比如股票、彩票數(shù)據(jù)
一成不變:果斷用緩存
偶爾更新:可以定期更改緩存策略 或者 清除緩存
提示:如果大量使用緩存 會(huì)越積越大 建議定期清除緩存
2、使用NSURLSession發(fā)送請(qǐng)求
1)創(chuàng)建一個(gè)NSURLSession對(duì)象,來幫助發(fā)送request請(qǐng)求
//數(shù)據(jù)請(qǐng)求,返回的是一個(gè)NSURLSessionDataTask對(duì)象,專門用來做數(shù)據(jù)類的網(wǎng)絡(luò)請(qǐng)求任務(wù)
[session dataTaskWithRequest:nil completionHandler:nil];
//上傳請(qǐng)求,返回的是一個(gè)NSURLSessionUploadTask對(duì)象,專門用來做上傳類的網(wǎng)絡(luò)請(qǐng)求任務(wù)
[session uploadTaskWithRequest:nil fromData:nil completionHandler:nil];
//下載請(qǐng)求,返回的是一個(gè)NSURLSessionDownloadTask對(duì)象,專門用來做下載類的網(wǎng)絡(luò)請(qǐng)求任務(wù)
[session downloadTaskWithRequest:nil completionHandler:nil];
2)開始請(qǐng)求
[sessionTask resume];
3、獲取響應(yīng)頭和相應(yīng)體信息
//獲取到相應(yīng)頭
NSHTTPURLResponse *httpResopnse = (NSHTTPURLResponse *)response;
//獲取響應(yīng)體
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
六:網(wǎng)絡(luò)環(huán)境判斷
Reachability
(1)導(dǎo)入類名
(2)創(chuàng)建對(duì)象 hostName盡量用一個(gè)穩(wěn)定的網(wǎng)絡(luò)
(3)添加觀察者? 接收網(wǎng)絡(luò)環(huán)境發(fā)生改變的通知 通知的名字 kReachabilityChangedNotification
(4)開始檢測(cè)
(5)在通知中得到 Reachability對(duì)象 not.object 獲得網(wǎng)絡(luò)環(huán)境的狀態(tài)
二、網(wǎng)絡(luò)下載文件
1、小文件下載使用block方式,不能監(jiān)聽下載進(jìn)度
1)準(zhǔn)備request
NSString *path = [NSString stringWithFormat:
path = [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString:path];
NSMutableURLRequest *reuqest = [NSMutableURLRequest requestWithURL:url];
2) 準(zhǔn)備發(fā)送請(qǐng)求的NSURLSession對(duì)象
NSURLSession *session = [NSURLSession sharedSession];
3)發(fā)送請(qǐng)求并獲得NSURLSessionDownloadTask對(duì)象,采用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)開始請(qǐng)求
[downloadTask resume];
2、大文件采用代理方式,能夠監(jiān)聽下載進(jìn)度
1)準(zhǔn)備request
NSURL *url = [NSURL URLWithString:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
2)獲取到發(fā)送請(qǐng)求的NSURLSession對(duì)象,并設(shè)置會(huì)話模式、代理(記得遵守下載的協(xié)議)、線程隊(duì)列
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
PS:三種會(huì)話方式
進(jìn)程內(nèi)會(huì)話(默認(rèn)會(huì)話),用硬盤來緩存數(shù)據(jù)。
defaultSessionConfiguration
臨時(shí)的進(jìn)程內(nèi)會(huì)話(內(nèi)存),不會(huì)將cookie、緩存儲(chǔ)存到本地,只會(huì)放到內(nèi)存中,當(dāng)應(yīng)用程序退出后數(shù)據(jù)也會(huì)消失
ephemeralSessionConfiguration
后臺(tái)會(huì)話,相比默認(rèn)會(huì)話,該會(huì)話會(huì)在后臺(tái)開啟一個(gè)線程進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)處理
backgroundSessionConfiguration
3)獲取到NSURLSessionDownloadTask對(duì)象,不需要用block
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
4) 實(shí)現(xiàn)代理方法
//下載完成時(shí)調(diào)用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSLog(@"finished=%@",NSHomeDirectory());
}
//下載過程中調(diào)用
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
//參數(shù)分別是
當(dāng)前這次下載的數(shù)據(jù)
已經(jīng)下載的總數(shù)據(jù)
期待下載的總數(shù)據(jù)
NSLog(@"%lld %lld %lld",bytesWritten,totalBytesWritten,totalBytesExpectedToWrite);
NSLog(@"%@",[NSThread currentThread]);
}
5)下載控制
//開始(恢復(fù))下載
[downloadTask resume];
//掛起下載
[downloadTask suspend];
//取消下載
[downloadTask cancel];
OSI網(wǎng)絡(luò)通訊協(xié)議模型,是一個(gè)參考模型,參考于他的TCP/IP協(xié)議才是目前網(wǎng)絡(luò)上通用的網(wǎng)絡(luò)通訊協(xié)議,接下來先了解一下TCP/IP協(xié)議。
通常所說的TCP/IP協(xié)議,其實(shí)是一個(gè)協(xié)議集合,這個(gè)集合里面包含了網(wǎng)絡(luò)通訊所需的所有協(xié)議,里面不僅有TCP(傳輸控制協(xié)議)、IP(網(wǎng)際協(xié)議),還有UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP、TFTP等許多協(xié)議,但因?yàn)門CP協(xié)議和IP協(xié)議是保證數(shù)據(jù)完整傳輸?shù)膬蓚€(gè)基本的重要協(xié)議,所以該協(xié)議集合就被命名為TCP/IP協(xié)議了。
TCP/IP協(xié)議的制定是參考于OSI模型的,但并沒有嚴(yán)格按照OSI規(guī)定的七層去劃分,而是劃分了四層,
應(yīng)用層
傳輸層
網(wǎng)絡(luò)層
網(wǎng)絡(luò)接口層
OSI和TCP/IP對(duì)比圖
目前我們已經(jīng)知道TCP/IP協(xié)議分為四個(gè)層次,我舉個(gè)例子簡(jiǎn)單說明一下各個(gè)層的作用,拿寄送郵件舉例,A寄郵件給B,A關(guān)心的是用什么格式寫什么內(nèi)容給B(應(yīng)用層內(nèi)容),是寄掛號(hào)信(信件丟失會(huì)賠償)還是寄平信(信件丟失不賠償)(應(yīng)用層內(nèi)容),A是不會(huì)關(guān)注郵件傳送過程中采用了哪條路線,郵遞員是如何把信地道B手里的(網(wǎng)絡(luò)層,網(wǎng)絡(luò)接口層)。接下來再詳細(xì)講一下應(yīng)用層和傳輸層。
傳輸層 傳輸層有多個(gè)協(xié)議,但最主要的是TCP和UDP協(xié)議。兩者的區(qū)別在與TCP協(xié)議需要接收方反饋,傳輸更可靠,而UDP協(xié)議雖然不需要反饋,但傳輸?shù)乃俾时容^高。,至于具體采用哪種方式,需要具體問題具體分析,在不可靠的網(wǎng)絡(luò)傳送過程中一般選擇TCP傳送方式,在講求效率或者不在乎傳輸失誤的情況下可以選擇UDP方式來提高傳輸速率。
應(yīng)用層 應(yīng)用層協(xié)議有很多,每一個(gè)協(xié)議代表一種類型的服務(wù)。
HTTP協(xié)議,萬(wàn)維網(wǎng)服務(wù)
FTP協(xié)議,文件傳送服務(wù)
POP3協(xié)議,郵件服務(wù)
二、利用Socket建立網(wǎng)絡(luò)連接的步驟
建立Socket連接至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶端,稱為ClientSocket ,另一個(gè)運(yùn)行于服務(wù)器端,稱為ServerSocket 。
套接字之間的連接過程分為三個(gè)步驟:服務(wù)器監(jiān)聽,客戶端請(qǐng)求,連接確認(rèn)。
1、服務(wù)器監(jiān)聽:服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請(qǐng)求。
2、客戶端請(qǐng)求:指客戶端的套接字提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的套接字。
為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號(hào),然后就向服務(wù)器端套接字提出連接請(qǐng)求。
3、連接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請(qǐng)求時(shí),就響應(yīng)客戶端套接字的請(qǐng)求,建立一個(gè)新的線程,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,雙方就正式建立連接。
而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請(qǐng)求。
三、HTTP鏈接的特點(diǎn)
HTTP協(xié)議即超文本傳送協(xié)議(Hypertext Transfer Protocol ),是Web聯(lián)網(wǎng)的基礎(chǔ),也是手機(jī)聯(lián)網(wǎng)常用的協(xié)議之一,HTTP協(xié)議是建立在TCP協(xié)議之上的一種應(yīng)用。
HTTP連接最顯著的特點(diǎn)是客戶端發(fā)送的每次請(qǐng)求都需要服務(wù)器回送響應(yīng),在請(qǐng)求結(jié)束后,會(huì)主動(dòng)釋放連接。從建立連接到關(guān)閉連接的過程稱為“一次連接”。
四、TCP和UDP的區(qū)別(考得最多。。快被考爛了我覺得- -\\)
1、TCP是面向鏈接的,雖然說網(wǎng)絡(luò)的不安全不穩(wěn)定特性決定了多少次握手都不能保證連接的可靠性,但TCP的三次握手在最低限度上(實(shí)際上也很大程度上保證了)保證了連接的可靠性;
而UDP不是面向連接的,UDP傳送數(shù)據(jù)前并不與對(duì)方建立連接,對(duì)接收到的數(shù)據(jù)也不發(fā)送確認(rèn)信號(hào),發(fā)送端不知道數(shù)據(jù)是否會(huì)正確接收,當(dāng)然也不用重發(fā),所以說UDP是無連接的、不可靠的一種數(shù)據(jù)傳輸協(xié)議。
2、也正由于1所說的特點(diǎn),使得UDP的開銷更小數(shù)據(jù)傳輸速率更高,因?yàn)椴槐剡M(jìn)行收發(fā)數(shù)據(jù)的確認(rèn),所以UDP的實(shí)時(shí)性更好。
知道了TCP和UDP的區(qū)別,就不難理解為何采用TCP傳輸協(xié)議的MSN比采用UDP的QQ傳輸文件慢了,但并不能說QQ的通信是不安全的,
因?yàn)槌绦騿T可以手動(dòng)對(duì)UDP的數(shù)據(jù)收發(fā)進(jìn)行驗(yàn)證,比如發(fā)送方對(duì)每個(gè)數(shù)據(jù)包進(jìn)行編號(hào)然后由接收方進(jìn)行驗(yàn)證啊什么的,
即使是這樣,UDP因?yàn)樵诘讓訁f(xié)議的封裝上沒有采用類似TCP的“三次握手”而實(shí)現(xiàn)了TCP所無法達(dá)到的傳輸效率。
