一、網(wǎng)絡(luò)基礎(chǔ)知識(shí)介紹
1、為什么要學(xué)習(xí)網(wǎng)絡(luò)編程?---pptx介紹。
2、網(wǎng)絡(luò)的基本概念---pptx介紹。
>什么是URL?
> HTTP簡(jiǎn)介
>網(wǎng)絡(luò)開發(fā)解決方案
(一)、蘋果原生(自帶)方案
1> NSURLConnection
* iOS2.0出現(xiàn),用法簡(jiǎn)單,最古老最經(jīng)典最直接的一種方案。
*在iOS5.0之前,使用起來(lái)相對(duì)繁瑣,一大堆的代理方法。
*在iOS5.0之后又作了一層改進(jìn),提供了兩個(gè)非常方便的方法,使發(fā)送網(wǎng)絡(luò)請(qǐng)求變得更簡(jiǎn)單。基本一句代碼就能解決簡(jiǎn)單的網(wǎng)絡(luò)處理了。
2> NSURLSession
* iOS7新出的技術(shù),與NSURLConnection是并列的。
*但功能比NSURLConnection更加強(qiáng)大,性能也比NSURLConnection好很多
*當(dāng)程序在前臺(tái)時(shí),NSURLSession和NSURLConnection大部分可以互相替代,但NSURLSession支持后臺(tái)網(wǎng)絡(luò)操作,除非用戶強(qiáng)行關(guān)閉。
*蘋果官方推薦使用NSURLSession代替NSURLConnection。
NSURLSession提供的功能:
1)通過(guò)URL將數(shù)據(jù)下載到內(nèi)存;
2)通過(guò)URL將數(shù)據(jù)下載到文件系統(tǒng);
3)將數(shù)據(jù)上傳到指定的URL;
4)在后臺(tái)完成上述功能.
5)支持下載,斷點(diǎn)續(xù)傳,后臺(tái)上傳/下載,后臺(tái)上傳/下載任務(wù)跟進(jìn)
3> CFNetwork:NSURL*的底層,純C語(yǔ)言,開發(fā)中幾乎不會(huì)用到。
(二)、第三方框架
1> ASIHttpRequest:外號(hào)“HTTP終結(jié)者”,功能極其強(qiáng)大,幾乎沒(méi)有它考慮不到的問(wèn)題,可惜2012年10月就停止更新,MRC環(huán)境。底層是CFNetwork。
2> AFNetworking:簡(jiǎn)單易用,提供了基本夠用的常用功能,維護(hù)和使用者多,使用它程序員可以不用知道什么URL,什么是線程,什么是線程間的通信。底層是NSURLSession和NSURLConnection。
3> MKNetworkKit:簡(jiǎn)單易用,產(chǎn)自三哥的故鄉(xiāng)印度,維護(hù)和使用者少。底層是NSURLConnection
>建議:為了提高開發(fā)效率,企業(yè)開發(fā)用的基本是第三方框架
3、NSURLConnection常用方法
>步驟
1)、創(chuàng)建NSURL對(duì)象,確定要訪問(wèn)的資源路徑
2)、根據(jù)url創(chuàng)建請(qǐng)求對(duì)象NSURLRequest,向服務(wù)器索要數(shù)據(jù)
3)、建立網(wǎng)絡(luò)鏈接,將請(qǐng)求對(duì)象(同步或異步)發(fā)送給服務(wù)器
>代碼演示--訪問(wèn)百度
// 1、NSURL :確定要訪問(wèn)的資源路徑
// m:mobile代表手機(jī)上訪問(wèn)的路徑,一般大公司都會(huì)提供一個(gè)專門手機(jī)上訪問(wèn)的路徑
NSURL *url = [NSURL URLWithString:@"http://m.baidu.com/"];
// 2、NSURLRequest:根據(jù)url創(chuàng)建請(qǐng)求對(duì)象,向服務(wù)器索要數(shù)據(jù)
NSURLRequest *reuqest = [NSURLRequest requestWithURL:url];
// 3、建立網(wǎng)絡(luò)鏈接,將請(qǐng)求(同步或異步)發(fā)送給服務(wù)器
[NSURLConnection sendAsynchronousRequest:reuqest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(@"------%@",data);
}];
4、sendAsynchronousRequest方法和參數(shù)解釋:
> sendAsynchronousRequest:是異步的,NSURLConnection會(huì)開啟一條線程,發(fā)送網(wǎng)絡(luò)請(qǐng)求。
> queue:隊(duì)列-->負(fù)責(zé)調(diào)度/執(zhí)行completionHandler的隊(duì)列。
> completionHandler:完成請(qǐng)求的回調(diào)block。表示收到服務(wù)器的響應(yīng)數(shù)據(jù)。
>如何選擇隊(duì)列?
*如果接收到數(shù)據(jù)后,需要直接更新UI,選擇主隊(duì)列。
*如果要做耗時(shí)操作,比如下載一個(gè)zip文件,下載完要進(jìn)行解壓縮操作,選擇新建一個(gè)隊(duì)列。
5、利用UIWebView加載請(qǐng)求百度返回的字符串---顯示百度首頁(yè)
// 1、NSURL :確定要訪問(wèn)的資源路徑
NSURL *url = [NSURL URLWithString:@"http://m.baidu.com/"];
// 2、NSURLRequest:根據(jù)url創(chuàng)建請(qǐng)求對(duì)象,向服務(wù)器索要數(shù)據(jù)
NSMutableURLRequest *reuqest = [NSMutableURLRequest requestWithURL:url];
// 2.1、告訴服務(wù)器額外的信息
//告訴服務(wù)器我是iPhone
[reuqest setValue:@"iPhone AppleWebKit"forHTTPHeaderField:@"User-Agent"];
// 3、建立網(wǎng)絡(luò)鏈接,將請(qǐng)求(同步或異步)發(fā)送給服務(wù)器
[NSURLConnection sendAsynchronousRequest:reuqest queue:[NSOperationQueue? mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成字符串
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// baseURL:加載資源的參照路徑。
[self.webView loadHTMLString:html baseURL:url];
}];
> NSMutableURLRequest對(duì)象的作用?
*根據(jù)url創(chuàng)建請(qǐng)求對(duì)象,向服務(wù)器索要數(shù)據(jù)
*告訴服務(wù)器額外的信息:設(shè)置請(qǐng)求頭和請(qǐng)求體。在網(wǎng)絡(luò)訪問(wèn)過(guò)程中,絕大多數(shù)的變化都是通過(guò)request對(duì)象設(shè)置。比如身份驗(yàn)證,Cookie,瀏覽器類型,超時(shí)時(shí)長(zhǎng)等。
二、Socket編程
1、網(wǎng)絡(luò)通訊三要素
> IP地址[主機(jī)名],英文全稱:Internet Protocol Address,又譯為網(wǎng)際協(xié)議地址
*網(wǎng)絡(luò)中設(shè)備的標(biāo)識(shí),用來(lái)唯一標(biāo)識(shí)每一臺(tái)計(jì)算機(jī)。通?,F(xiàn)在常用的IP地址是IPV4地址。
* IPV4就是有4段數(shù)字,格式是xxx.xxx.xxx.xxx。每一段數(shù)字由8位二進(jìn)制做成,取值范圍是0~255。
* IPV4采用32位地址長(zhǎng)度,只有大約43億個(gè)地址。IPv4定義的有限地址空間將被耗盡。
*為了擴(kuò)大地址空間,擬通過(guò)IPV6重新定義地址空間。IPv6采用128位地址長(zhǎng)度。幾乎可以不受限制地提供地址。但I(xiàn)PV6現(xiàn)在還沒(méi)有正式普及。
*為了解決IPV4有限地址空間的問(wèn)題,IP地址又分內(nèi)網(wǎng)地址和外網(wǎng)地址。(比如校園網(wǎng),每一個(gè)學(xué)生都會(huì)有一個(gè)內(nèi)網(wǎng)地址,學(xué)校會(huì)有一個(gè)路由器,路由器會(huì)有個(gè)外網(wǎng)地址,學(xué)生想要上外網(wǎng)都必須通過(guò)路由器出去,只要通過(guò)同一個(gè)路由器出去的,他們對(duì)應(yīng)的外網(wǎng)地址都是一樣的)
*本質(zhì)上所有的網(wǎng)絡(luò)訪問(wèn)是通過(guò)ip地址訪問(wèn)的。域名是一個(gè)速記符號(hào),不用記住IP地址復(fù)雜的數(shù)字。
*本地回環(huán)地址:127.0.0.1主機(jī)名:localhost
>每臺(tái)計(jì)算機(jī)都有一個(gè)127.0.0.1
>如果127.0.0.1ping不通,說(shuō)明網(wǎng)卡不工作(比如裝黑蘋果,檢測(cè)網(wǎng)卡驅(qū)動(dòng)有沒(méi)裝好,可以ping下回環(huán)地址)
>如果本機(jī)地址ping不通,說(shuō)明網(wǎng)線壞了。
TIP:通過(guò)ip138.com可以速查某個(gè)域名對(duì)應(yīng)的IP地址。
>端口號(hào)
1)、通過(guò)打電話例子說(shuō)明端口號(hào)的作用
*很多網(wǎng)絡(luò)概念來(lái)源于電話
*電話號(hào)碼類似IP
*分機(jī)號(hào)類似于端口
2)、端口號(hào)的作用
*用來(lái)標(biāo)識(shí)進(jìn)程的邏輯地址,不同進(jìn)程的標(biāo)識(shí)。
*有效的端口:0~65535。
*其中0~1024由系統(tǒng)使用或保留端口。
*開發(fā)中不要使用1024以下的端口。
(端口有什么用呢?我們知道,一臺(tái)擁有IP地址的主機(jī)可以提供許多服務(wù),比如Web服務(wù)、FTP服務(wù)、SMTP服務(wù)等,這些服務(wù)完全可以通過(guò)1個(gè)IP地址來(lái)實(shí)現(xiàn)。那么,主機(jī)是怎樣區(qū)分不同的網(wǎng)絡(luò)服務(wù)呢?顯然不能只靠IP地址,因?yàn)镮P地址與網(wǎng)絡(luò)服務(wù)的關(guān)系是一對(duì)多的關(guān)系。實(shí)際上是通過(guò)“IP地址+端口號(hào)”來(lái)區(qū)分不同的服務(wù)的。)
>傳輸協(xié)議(通信規(guī)則)--->(需要先學(xué)習(xí)OSI網(wǎng)絡(luò)模型)
1)、UDP(用戶數(shù)據(jù)報(bào)協(xié)議)
*面向無(wú)連接的協(xié)議
*只管發(fā)送,不確認(rèn)對(duì)方是否接收到
*將數(shù)據(jù)資源和目的封裝成數(shù)據(jù)包中,不需要建立連接
*每個(gè)數(shù)據(jù)包的大小限制在64K之內(nèi)
*因?yàn)闊o(wú)需連接,因此是不可靠協(xié)議
*不需要建立連接,速度快
*理解發(fā)電報(bào)的特點(diǎn)就理解了UDP協(xié)議的特點(diǎn)。
/*
舉例:地下黨給組織或上級(jí)發(fā)電報(bào)。
*/
2)、TCP(Transmission Control Protocol,傳輸控制協(xié)議)
*面向連接的協(xié)議。
*建立連接,形成傳輸數(shù)據(jù)的通道
*在連接中進(jìn)行大數(shù)據(jù)傳輸(數(shù)據(jù)大小不受限制)
*通過(guò)三次握手完成連接,是可靠協(xié)議,安全送達(dá)
*必須建立連接,效率會(huì)稍低
/*
簡(jiǎn)單的描述下三次握手的過(guò)程:主機(jī)A向主機(jī)B發(fā)出連接請(qǐng)求數(shù)據(jù)包:“我想給你發(fā)數(shù)據(jù),可以嗎?”,這是第一次對(duì)話;主機(jī)B向主機(jī)A發(fā)送同意連接和要求同步(同步就是兩臺(tái)主機(jī)一個(gè)在發(fā)送,一個(gè)在接收,協(xié)調(diào)工作)的數(shù)據(jù)包:“可以,你什么時(shí)候發(fā)?”,這是第二次對(duì)話;主機(jī)A再發(fā)出一個(gè)數(shù)據(jù)包確認(rèn)主機(jī)B的要求同步:“我現(xiàn)在就發(fā),你接著吧!”,這是第三次對(duì)話。三次“對(duì)話”的目的是使數(shù)據(jù)包的發(fā)送和接收同步,經(jīng)過(guò)三次“對(duì)話”之后,主機(jī)A才向主機(jī)B正式發(fā)送數(shù)據(jù)。
*/
3)、使用場(chǎng)合
* tcp一般用于文件傳輸(ftp http對(duì)數(shù)據(jù)準(zhǔn)確性要求高,速度可以相對(duì)慢),發(fā)送或接收郵件(pop imap smtp對(duì)數(shù)據(jù)準(zhǔn)確性要求高,非緊急應(yīng)用),遠(yuǎn)程登錄(telnet ssh對(duì)數(shù)據(jù)準(zhǔn)確性有一定要求,有連接的概念)等等;
* UDP一般用于即時(shí)通信(qq聊天對(duì)數(shù)據(jù)準(zhǔn)確性和丟包要求比較低,但速度必須快),在線視頻(rtsp速度一定要快,保證視頻連續(xù),但是偶爾花了一個(gè)圖像幀,人們還是能接受的),網(wǎng)絡(luò)語(yǔ)音電話(VoIP語(yǔ)音數(shù)據(jù)包一般比較小,需要高速發(fā)送,偶爾斷音或串音也沒(méi)有問(wèn)題)等等。
網(wǎng)絡(luò)通訊三要素歸納一句話:通過(guò)ip找機(jī)器,通過(guò)端口找程序,通過(guò)協(xié)議確定如何傳輸數(shù)據(jù)。
2、OSI網(wǎng)絡(luò)模型
> OSI(Open System Interconnect),即開放式系統(tǒng)互聯(lián)。一般都叫OSI參考模型,是ISO(國(guó)際標(biāo)準(zhǔn)化組織)組織在1985年研究的網(wǎng)絡(luò)互聯(lián)模型。
>該體系結(jié)構(gòu)標(biāo)準(zhǔn)定義了網(wǎng)絡(luò)互連的七層框架:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會(huì)話層、表示層和應(yīng)用層。數(shù)據(jù)發(fā)送時(shí),從第七層傳到第一層,接收數(shù)據(jù)則相反。
三、Socket簡(jiǎn)介
1、pptx介紹。
2、socket的建立和連接
1>導(dǎo)入三個(gè)頭文件
#import
#import
#import
2>創(chuàng)建socket
/**
參數(shù)
domain:協(xié)議域/協(xié)議族,AF_INET(IPV4的網(wǎng)絡(luò)開發(fā))
type:????? Socket類型,SOCK_STREAM(TCP)/SOCK_DGRAM(UDP,報(bào)文)
protocol:? IPPROTO_TCP,協(xié)議,如果輸入0,可以根據(jù)第二個(gè)參數(shù)自動(dòng)選擇協(xié)議
返回值
socket,如果>0就表示成功
*/
intclientSocket = socket(AF_INET, SOCK_STREAM,0);
3>連接到服務(wù)器
/**
參數(shù)
1>客戶端socket
2>指向數(shù)據(jù)結(jié)構(gòu)sockaddr的指針,其中包括目的端口和IP地址。即服務(wù)器的“結(jié)構(gòu)體”地址
3>結(jié)構(gòu)體數(shù)據(jù)長(zhǎng)度
返回值
0成功/其他錯(cuò)誤代號(hào),非0即真
*/
structsockaddr_in serverAddress;
//協(xié)議族
serverAddress.sin_family = AF_INET;
// ip找機(jī)器
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
//端口號(hào)找程序
serverAddress.sin_port = htons(12345);
//連接服務(wù)器
intresult =? connect(clientSocket, (conststructsockaddr *)&serverAddress,sizeof(serverAddress));
if(result ==0) {
NSLog(@"成功");
}else{
NSLog(@"失敗");
}
TIP:
>在C語(yǔ)言開發(fā)時(shí),如果要傳遞結(jié)構(gòu)體的地址,通常會(huì)一起傳遞結(jié)構(gòu)的長(zhǎng)度。因?yàn)镃語(yǔ)言中取數(shù)據(jù)是通過(guò)指針尋址的,告訴長(zhǎng)度的目的是防止取錯(cuò)數(shù)據(jù)。
>在終端輸入:nc -lk12345相當(dāng)于在本機(jī)上啟動(dòng)了一個(gè)服務(wù)器,ip是本機(jī)地址,端口號(hào)是12345。
4>發(fā)送和接收數(shù)據(jù)
//發(fā)送數(shù)據(jù)
/**
參數(shù)
1>客戶端socket
2>發(fā)送內(nèi)容地址void * == id
3>發(fā)送內(nèi)容長(zhǎng)度,是指字節(jié)的長(zhǎng)度。
4>發(fā)送方式標(biāo)志,一般為0
返回值
如果成功,則返回發(fā)送的字節(jié)數(shù),失敗則返回SOCKET_ERROR
*/
NSString *msg =@"約?";
ssize_t sendLenght =? send(clientSocket, msg.UTF8String, strlen(msg.UTF8String),0);
NSLog(@"發(fā)送了%ld長(zhǎng)度的字節(jié),字符串長(zhǎng)度%zd",sendLenght,msg.length);
//接收數(shù)據(jù)
/**
參數(shù)
1>客戶端socket
2>接收內(nèi)容地址
3>長(zhǎng)度,表示一次最多接收服務(wù)器返回的多少字節(jié)內(nèi)容。
4>接收標(biāo)志,一般填0,標(biāo)示阻塞式的,一直等待服務(wù)器服務(wù)器返回?cái)?shù)據(jù)
返回值
接收數(shù)據(jù)的長(zhǎng)度
*/
//緩沖區(qū),準(zhǔn)備接受來(lái)自服務(wù)器的數(shù)據(jù)
// C語(yǔ)言中,數(shù)組的名字,就是指向數(shù)組第一個(gè)元素的指針。
uint8_t buffer[1024];
ssize_t recvLen = recv(clientSocket, buffer,sizeof(buffer),0);
NSLog(@"接收%ld字節(jié)",recvLen);
//獲得服務(wù)器返回的二進(jìn)制數(shù)據(jù)
NSData *data = [NSData dataWithBytes:buffer length:recvLen];
//將二進(jìn)制數(shù)據(jù)轉(zhuǎn)化成字符串
NSString *resultStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"接收到的內(nèi)容是:%@",resultStr);
5>關(guān)閉連接
//斷開連接
close(clientSocket);
四、Socket聊天示例
>補(bǔ)充:智能家居原理介紹。
五、通訊過(guò)程
1> socket發(fā)送http請(qǐng)求--->請(qǐng)求本地apache服務(wù)器
準(zhǔn)備工作:
> Mac自帶了Apache服務(wù)器,啟動(dòng)apache服務(wù)器。
>相關(guān)命令
* sudo apachectl -v,顯示apache版本。
* sudo apachectl start,啟動(dòng)apache。
代碼實(shí)現(xiàn):
//建立連接
if(![selfconnectionToHost:@"127.0.0.1"port:80]) {
NSLog(@"失敗");
return;
}
NSLog(@"成功");
//向服務(wù)器發(fā)送請(qǐng)求數(shù)據(jù)
NSString *result =? [selfsendAndRecv:@"我要成為牛逼的程序員"];
NSLog(@"%@",result);
提問(wèn):給服務(wù)器發(fā)送的數(shù)據(jù),服務(wù)器能接收到嗎?會(huì)有響應(yīng)結(jié)果嗎?
>能接收到數(shù)據(jù),但是不會(huì)有任何響應(yīng)結(jié)果。原因是服務(wù)器不知道客戶端發(fā)送的內(nèi)容是什么。
思考
1)、客戶端該傳什么格式的數(shù)據(jù)給服務(wù)器?服務(wù)器才能看懂。
2)、服務(wù)器該返回什么格式的數(shù)據(jù)給客戶端?客戶端才能看懂。
//向服務(wù)器發(fā)送請(qǐng)求數(shù)據(jù)
//請(qǐng)求字符串,指定請(qǐng)求頭和請(qǐng)求行
NSString *request =@"GET /abcd.txt HTTP/1.1\r\n"
"Host:localhost\r\n\r\n";
/**
URL與請(qǐng)求的對(duì)應(yīng)關(guān)系:
比如URL是:http://localhost/abcd.txt其中協(xié)議頭https是由HTTP/1.1指定的,主機(jī)地址是由Host:localhost指定的,路徑是由/abcd.txt指定的
*/
NSString *result =? [selfsendAndRecv:request];
NSLog(@"%@",result);
#獲得本地apache服務(wù)器的根目錄:
#在終端輸入命令more /etc/apache2/httpd.conf回車
#搜索DocumentRoot得到/Library/WebServer/Documents
2> socket發(fā)送http請(qǐng)求--->請(qǐng)求遠(yuǎn)程服務(wù)器(百度,京東,起點(diǎn))
/**
*連接遠(yuǎn)程服務(wù)器(百度,京東,起點(diǎn))
*/
- (void)connectionToRometionServer{
//百度:域名m.baidu.comip:61.135.185.17
//起點(diǎn):域名m.qidian.comip:36.250.76.204
//京東:域名m.jd.comip:111.206.227.150
//建立連接
if(![selfconnectionToHost:@"111.206.227.150"port:80]) {
NSLog(@"失敗");
return;
}
NSLog(@"成功");
//向服務(wù)器發(fā)送請(qǐng)求數(shù)據(jù)
NSString *request =@"GET / HTTP/1.1\r\n"
"Host:m.jd.com\r\n"
"User-Agent:iPhone AppleWebKit\r\n"
"Connection:Close\r\n\r\n";
NSString *result =? [selfsendAndRecv:request];
//在返回結(jié)果中查找\r\n\r\n,目的是取出響應(yīng)狀態(tài)行和響應(yīng)頭的內(nèi)容
NSRange range = [result rangeOfString:@"\r\n\r\n"];
if(range.location != NSNotFound) {
NSString *html = [result substringFromIndex:range.location];
NSLog(@"=======> %@",html);
//加載網(wǎng)頁(yè)
[self.webView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://m.jd.com"]];
}
NSLog(@"--------%@",result);
}
#TIP:ping域名就能得到對(duì)應(yīng)網(wǎng)站的ip地址。
非持續(xù)連接和持續(xù)連接的區(qū)別:
>非持續(xù)連接是指啟動(dòng)一次TCP連接服務(wù)器就向客戶端傳送一個(gè)對(duì)象,而持續(xù)連接是指服務(wù)器可在相同的TCP連接上向客戶端發(fā)送多個(gè)對(duì)象。HTTP/1.0的默認(rèn)設(shè)置是非持續(xù)連接,而HTTP/1.1的默認(rèn)設(shè)置是持續(xù)連接。
>舉個(gè)例子
在使用HTTP/1.0的情況下,如果打開一個(gè)包含一個(gè)HTML文件和10個(gè)內(nèi)聯(lián)圖象對(duì)象的網(wǎng)頁(yè)時(shí),HTTP就要建立11次TCP連接才能把文件從服務(wù)器傳送到客戶端。而使用HTTP/1.1的情況下,如果打開同樣的文件時(shí),HTTP建立一次TCP連接就可把文件從服務(wù)器傳送到客戶端。
3> Http通訊過(guò)程
1、建立請(qǐng)求:
HTTP協(xié)議規(guī)定:一個(gè)完整的由客戶端發(fā)給服務(wù)器的HTTP請(qǐng)求需要包含以下內(nèi)容:
1)、請(qǐng)求行:指定請(qǐng)求方法、請(qǐng)求資源路徑以及HTTP協(xié)議版本。
# /表示訪問(wèn)根目錄
GET / HTTP/1.1
2)、請(qǐng)求頭:對(duì)客戶端的環(huán)境描述、客戶端請(qǐng)求的主機(jī)地址等信息。
*請(qǐng)求頭中至少包含以下信息
#客戶端要訪問(wèn)的服務(wù)器主機(jī)地址
Host:m.baidu.com
*請(qǐng)求頭中還可以包含以下信息
#客戶端的類型,客戶端的軟件環(huán)境
User-Agent:iPhone AppleWebKit
#客戶端所能接收的數(shù)據(jù)類型
Accept:text/html
#客戶端的語(yǔ)言環(huán)境
Accept-Language:zh-cn
#客戶端支持的數(shù)據(jù)壓縮格式
Accept-Encoding:gzip
#訪問(wèn)結(jié)束后,是否斷開連接
Connection:Close
3)、請(qǐng)求體(可選):客戶端發(fā)給服務(wù)器的具體數(shù)據(jù),例如要上傳的文件數(shù)據(jù)。
請(qǐng)求格式:
>每一項(xiàng)請(qǐng)求信息末尾使用\r\n
>最后一個(gè)請(qǐng)求項(xiàng)末尾使用\r\n\r\n表示請(qǐng)求結(jié)束
#warming每一項(xiàng)請(qǐng)求信息和\r\n之間不能有空格。
2、接收響應(yīng)
客戶端向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器應(yīng)當(dāng)做出響應(yīng),即返回給客戶端的數(shù)據(jù)
HTTP協(xié)議規(guī)定:1個(gè)完整的HTTP響應(yīng)中包含以下內(nèi)容
1)、狀態(tài)行:包含了HTTP協(xié)議版本、狀態(tài)碼、狀態(tài)英文名稱
#HTTP/1.1200OK
2)、響應(yīng)頭:包含了對(duì)服務(wù)器的描述、對(duì)返回?cái)?shù)據(jù)的描述
#Server: Apache-Coyote/1.1//服務(wù)器的類型
#Content-Type: image/jpeg//返回?cái)?shù)據(jù)的類型
#Content-Length:56811//返回?cái)?shù)據(jù)的長(zhǎng)度
#Date: Mon,23Jun201412:54:52GMT//響應(yīng)的時(shí)間
3)、實(shí)體內(nèi)容:服務(wù)器返回給客戶端的具體數(shù)據(jù),比如文件數(shù)據(jù)
七、NSURLConnection常用方法使用
1、服務(wù)器響應(yīng)演練。
/**
*加載數(shù)據(jù)
*/
- (void)loadData{
// 1.創(chuàng)建url
NSURL *url = [NSURL URLWithString:@"http://pinyin.sogou.com/"];
// 2.創(chuàng)建請(qǐng)求對(duì)象
//??? NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36"forHTTPHeaderField:@"User-Agent"];
// 3.發(fā)送異步請(qǐng)求到服務(wù)器(所有的網(wǎng)絡(luò)請(qǐng)求都是耗時(shí)操作,因此絕大多數(shù)都是異步請(qǐng)求)
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(@"%@---%@--%@---%@----%@",response,response.MIMEType,response.URL,response.textEncodingName,response.suggestedFilename);
[self.webView loadData:data MIMEType:response.MIMEType textEncodingName:response.textEncodingName baseURL:url];
}];
}
> response:本質(zhì)上就是NSHTTPURLResponse從服務(wù)器上獲得的響應(yīng)
NSURLResponse相關(guān)屬性:
- URL:響應(yīng)url,一般用來(lái)重定向使用。瀏覽器演示什么是重定向,百度搜索搜狗輸入法。(沒(méi)有重定向的情況下,響應(yīng)url和請(qǐng)求url是相同)
- MIMEType:請(qǐng)求數(shù)據(jù)的數(shù)據(jù)類型,服務(wù)器告訴客戶端的返回的數(shù)據(jù)是什么類型。
Content-Type等價(jià)MIMEType,客戶端根據(jù)MIMEType決定用什么來(lái)打開或顯示返回的數(shù)據(jù)。(典型的列子就是瀏覽器裝flash插件的例子。當(dāng)在瀏覽器中看視頻的時(shí)候,瀏覽器都會(huì)提示要安裝flash插件,否則無(wú)法觀看,瀏覽器就是通過(guò)MIMEType來(lái)判斷觀看視頻需要flash插件的支持。)
- textEncodingName:返回內(nèi)容的編碼方式
以下兩個(gè)屬性通常用于開發(fā)下載
- expectedContentLength:請(qǐng)求二進(jìn)制數(shù)據(jù)的長(zhǎng)度,下載文件的大小
- suggestedFilename:建議保存的文件名,服務(wù)器建議下載文件保存時(shí)使用的文件名,一般mac下下載文件不需要填寫保存的文件名,就是因?yàn)闉g覽器客戶端根據(jù)服務(wù)器返回的該字段作為文件名了。
2、錯(cuò)誤處理:在實(shí)際開發(fā)中,一定要處理錯(cuò)誤!任何的網(wǎng)絡(luò)請(qǐng)求都有可能出錯(cuò)!比如流量沒(méi)了,網(wǎng)絡(luò)斷了,沒(méi)信號(hào)了。
//有時(shí)候沒(méi)有錯(cuò)誤,但也沒(méi)有數(shù)據(jù)
if(connectionError !=nil|| data ==nil) {
//提示用戶最好友善點(diǎn),不要太專業(yè)了。比如提示出現(xiàn)404錯(cuò)誤,或500錯(cuò)誤了。用戶不會(huì)理解這些專業(yè)術(shù)語(yǔ)的。
NSLog(@"你的網(wǎng)絡(luò)不給力哦!");
return;
}
3、超時(shí)時(shí)長(zhǎng)和緩存策略
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0timeoutInterval:15];
- cachePolicy:緩存策略
NSURLRequestUseProtocolCachePolicy =0,默認(rèn)的緩存策略
NSURLRequestReloadIgnoringLocalCacheData =1,忽略本地緩存數(shù)據(jù)
一般應(yīng)用于對(duì)數(shù)據(jù)‘實(shí)時(shí)性要求高’的應(yīng)用每次都從服務(wù)器加載數(shù)據(jù)
應(yīng)用場(chǎng)景:12306,股票,彩票等
NSURLRequestReloadIgnoringLocalAndRemoteCacheData =4,沒(méi)有實(shí)現(xiàn)的緩存策略,可忽略
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
//以下兩項(xiàng)做離線應(yīng)用
//在實(shí)際開發(fā)中,要盡量讓用戶回到網(wǎng)絡(luò)上!
NSURLRequestReturnCacheDataElseLoad =2,有緩存,就返回緩存數(shù)據(jù),否則從服務(wù)器中加載。
NSURLRequestReturnCacheDataDontLoad =3,有緩存,就返回緩存數(shù)據(jù),否則不加載。
如果應(yīng)用需要通過(guò)廣告,展現(xiàn)率,點(diǎn)擊率,成交率來(lái)獲得收入的,建議不要做離線緩存,原因主要有兩點(diǎn):
1>開發(fā)困難且周期長(zhǎng),需要設(shè)計(jì)兩個(gè)數(shù)據(jù)庫(kù),一個(gè)本地?cái)?shù)據(jù)庫(kù),用來(lái)緩存數(shù)據(jù),一個(gè)遠(yuǎn)程數(shù)據(jù)庫(kù)。
2>廣告,展現(xiàn)率,點(diǎn)擊率,成交率等操作都是基于網(wǎng)絡(luò)的,離線不使用網(wǎng)絡(luò)就無(wú)法產(chǎn)生收入。
NSURLRequestReloadRevalidatingCacheData =5,沒(méi)有實(shí)現(xiàn)的緩存策略,可忽略
- timeoutInterval:請(qǐng)求的超時(shí)時(shí)長(zhǎng),在指定的時(shí)間內(nèi),如果沒(méi)有收到服務(wù)器的反饋,認(rèn)為請(qǐng)求失敗。
系統(tǒng)默認(rèn)60s
SDWebImage超時(shí)時(shí)長(zhǎng)15s
AFN超時(shí)時(shí)長(zhǎng)60s
建議:不要太短,也不要太長(zhǎng)。在15s~30s之間最合適