一彪置、iOS9 網絡編程的重大改變:
1、網絡請求方式的改變
1)NSURLConnection: iOS9之前使用
2)NSURLSession: iOS9 使用這個類
2、后臺服務器傳輸協議由HTTP改成HTTPS
1)iOS開發(fā) -> info.plist -> App Transport Security Settings ->Allow Arbitrary Loads -> YES
I
二惕稻、URL:
1、概念:
Uniform Resource Locator 統(tǒng)一資源定位符
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最初的目的是為了提供一種 發(fā)布和接收 HTML頁面的方法。1960年美國人Ted Nelson構思了一種通過計算機處理文本信息的方法拾碌,并稱之為超文本(hypertext),這成為了HTTP超文本傳輸協議標準架構的發(fā)展根基
是用于從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議
3吐葱、通訊流程
1)首先客戶端發(fā)送一個請求(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蔫敲、發(fā)送了一個請求 沒有任何回應
1)沒聯網
2)請求內容錯誤:URL
練習:通過瀏覽器了解HTTP請求過程
四扑浸、JSON和XML
1、基本概念
查看博客 http://www.reibang.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)獲取到根節(jié)點
GDataXMLElement *rootElement = [document rootElement];
4)取出節(jié)點的屬性值
[element attributeForName:@"id"]
4)根據節(jié)點取值
[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
有緩存就用緩存 沒有緩存就不發(fā)請求 當做請求出錯處理(用于離線模式)
NSURLRequestReturnCacheDataDontLoad
3)緩存策略的選擇接癌,如果請求某個URL的返回數據
經常更新:不能用緩存 比如股票心赶、彩票數據
一成不變:果斷用緩存
偶爾更新:可以定期更改緩存策略 或者 清除緩存
提示:如果大量使用緩存 會越積越大 建議定期清除緩存
2、使用NSURLSession發(fā)送請求
1)創(chuàng)建一個NSURLSession對象缺猛,來幫助發(fā)送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];
六:網絡環(huán)境判斷
Reachability
(1)導入類名
(2)創(chuàng)建對象 hostName盡量用一個穩(wěn)定的網絡
(3)添加觀察者? 接收網絡環(huán)境發(fā)生改變的通知 通知的名字 kReachabilityChangedNotification
(4)開始檢測
(5)在通知中得到 Reachability對象 not.object 獲得網絡環(huán)境的狀態(tài)
二蒸健、網絡下載文件
1、小文件下載使用block方式鸽嫂,不能監(jiān)聽下載進度
1)準備request
NSString *path = [NSString stringWithFormat:
path = [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString:path];
NSMutableURLRequest *reuqest = [NSMutableURLRequest requestWithURL:url];
2) 準備發(fā)送請求的NSURLSession對象
NSURLSession *session = [NSURLSession sharedSession];
3)發(fā)送請求并獲得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征讲、大文件采用代理方式据某,能夠監(jiān)聽下載進度
1)準備request
NSURL *url = [NSURL URLWithString:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
2)獲取到發(fā)送請求的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規(guī)定的七層去劃分嚣潜,而是劃分了四層冬骚,
應用層
傳輸層
網絡層
網絡接口層
OSI和TCP/IP對比圖
目前我們已經知道TCP/IP協議分為四個層次,我舉個例子簡單說明一下各個層的作用懂算,拿寄送郵件舉例只冻,A寄郵件給B,A關心的是用什么格式寫什么內容給B(應用層內容)计技,是寄掛號信(信件丟失會賠償)還是寄平信(信件丟失不賠償)(應用層內容)喜德,A是不會關注郵件傳送過程中采用了哪條路線,郵遞員是如何把信地道B手里的(網絡層垮媒,網絡接口層)舍悯。接下來再詳細講一下應用層和傳輸層。
傳輸層 傳輸層有多個協議睡雇,但最主要的是TCP和UDP協議萌衬。兩者的區(qū)別在與TCP協議需要接收方反饋,傳輸更可靠它抱,而UDP協議雖然不需要反饋秕豫,但傳輸的速率比較高。观蓄,至于具體采用哪種方式馁蒂,需要具體問題具體分析,在不可靠的網絡傳送過程中一般選擇TCP傳送方式蜘腌,在講求效率或者不在乎傳輸失誤的情況下可以選擇UDP方式來提高傳輸速率沫屡。
應用層 應用層協議有很多,每一個協議代表一種類型的服務撮珠。
HTTP協議沮脖,萬維網服務
FTP協議,文件傳送服務
POP3協議芯急,郵件服務
二勺届、利用Socket建立網絡連接的步驟
建立Socket連接至少需要一對套接字,其中一個運行于客戶端娶耍,稱為ClientSocket 免姿,另一個運行于服務器端,稱為ServerSocket 榕酒。
套接字之間的連接過程分為三個步驟:服務器監(jiān)聽胚膊,客戶端請求故俐,連接確認。
1紊婉、服務器監(jiān)聽:服務器端套接字并不定位具體的客戶端套接字药版,而是處于等待連接的狀態(tài),實時監(jiān)控網絡狀態(tài)喻犁,等待客戶端的連接請求槽片。
2、客戶端請求:指客戶端的套接字提出連接請求肢础,要連接的目標是服務器端的套接字还栓。
為此,客戶端的套接字必須首先描述它要連接的服務器的套接字传轰,指出服務器端套接字的地址和端口號剩盒,然后就向服務器端套接字提出連接請求。
3路召、連接確認:當服務器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求時勃刨,就響應客戶端套接字的請求波材,建立一個新的線程股淡,把服務器端套接字的描述發(fā)給客戶端,一旦客戶端確認了此描述廷区,雙方就正式建立連接唯灵。
而服務器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求隙轻。
三埠帕、HTTP鏈接的特點
HTTP協議即超文本傳送協議(Hypertext Transfer Protocol ),是Web聯網的基礎玖绿,也是手機聯網常用的協議之一敛瓷,HTTP協議是建立在TCP協議之上的一種應用。
HTTP連接最顯著的特點是客戶端發(fā)送的每次請求都需要服務器回送響應斑匪,在請求結束后呐籽,會主動釋放連接。從建立連接到關閉連接的過程稱為“一次連接”蚀瘸。
四狡蝶、TCP和UDP的區(qū)別(考得最多。贮勃√叭牵快被考爛了我覺得- -\\)
1、TCP是面向鏈接的寂嘉,雖然說網絡的不安全不穩(wěn)定特性決定了多少次握手都不能保證連接的可靠性奏瞬,但TCP的三次握手在最低限度上(實際上也很大程度上保證了)保證了連接的可靠性;
而UDP不是面向連接的枫绅,UDP傳送數據前并不與對方建立連接,對接收到的數據也不發(fā)送確認信號丝格,發(fā)送端不知道數據是否會正確接收撑瞧,當然也不用重發(fā),所以說UDP是無連接的显蝌、不可靠的一種數據傳輸協議预伺。
2、也正由于1所說的特點曼尊,使得UDP的開銷更小數據傳輸速率更高酬诀,因為不必進行收發(fā)數據的確認,所以UDP的實時性更好骆撇。
知道了TCP和UDP的區(qū)別瞒御,就不難理解為何采用TCP傳輸協議的MSN比采用UDP的QQ傳輸文件慢了,但并不能說QQ的通信是不安全的神郊,
因為程序員可以手動對UDP的數據收發(fā)進行驗證肴裙,比如發(fā)送方對每個數據包進行編號然后由接收方進行驗證啊什么的逆瑞,
即使是這樣纯趋,UDP因為在底層協議的封裝上沒有采用類似TCP的“三次握手”而實現了TCP所無法達到的傳輸效率蓬抄。