網(wǎng)絡(luò)01

1.為什么學(xué)習(xí)網(wǎng)絡(luò)?

1.1 學(xué)習(xí)網(wǎng)絡(luò)是學(xué)習(xí)實(shí)時(shí)更新數(shù)據(jù)的手段
1.2 掌握了實(shí)時(shí)更新數(shù)據(jù)的手段,可以使APP變得更加有吸引力
1.3 數(shù)據(jù)的實(shí)時(shí)的更新是在服務(wù)器端發(fā)生的
1.4 客戶端只需要把服務(wù)器最新的數(shù)據(jù)加載到客戶端,然后展示即可
1.5 客戶端的網(wǎng)絡(luò)開發(fā)只做一件事,向服務(wù)器發(fā)送網(wǎng)絡(luò)請求,得到服務(wù)器的"最新"數(shù)據(jù)展示在界面上
1.6 客戶端的開發(fā)者,只需要關(guān)心"請求怎么發(fā),響應(yīng)怎么處理"

2.網(wǎng)絡(luò)核心

2.1 客戶端 : 就是手機(jī) / APP
2.2 服務(wù)器端 : 為客戶端提供數(shù)據(jù)的"特殊"的計(jì)算機(jī)
2.3 請求 : 客戶端向服務(wù)器端獲取數(shù)據(jù)的行為
2.4 響應(yīng) : 服務(wù)器端對客戶端的請求作出的反應(yīng)

3.網(wǎng)絡(luò)開發(fā)的結(jié)構(gòu)

3.1 客戶端 : 發(fā)送請求,告訴服務(wù)器自己要什么數(shù)據(jù)
3.2 服務(wù)器端 : 服務(wù)器得到客戶端的請求之后,就去數(shù)據(jù)庫里面找客戶端需要的數(shù)據(jù),如果找到就把數(shù)據(jù)發(fā)送客戶端
3.3 數(shù)據(jù)庫 : 專門存放數(shù)據(jù)的地方
3.4 實(shí)際開發(fā)中,作為移動(dòng)端開發(fā),只需要關(guān)心客戶端的開發(fā)就可以了

4.服務(wù)器

4.1 測試服務(wù)器 : 在開發(fā)階段使用的服務(wù)器,是本地的,所以數(shù)據(jù)加載比較快,方便前后端開發(fā)者調(diào)節(jié)數(shù)據(jù)
4.2 正式服務(wù)器 : APP發(fā)布上線之后,訪問的服務(wù)器;里面的數(shù)據(jù)都是正確的,可以被任何備用戶訪問
4.3 黑馬學(xué)習(xí)網(wǎng)絡(luò)課程,選擇的是本地apache服務(wù)器,只在學(xué)習(xí)時(shí)使用;實(shí)際開發(fā),使用自己公司的測試和正式服務(wù)器

5.URL

http://open.api.yaolan.com/api/bbs/post?limit=20&start=0&source=ios&tid=53251140&token=3784

5.1 URL的概念 : 統(tǒng)一資源定位符 (數(shù)據(jù)在網(wǎng)絡(luò)中的路徑 / 地址)

5.1.1 通過唯一的URL可以獲取到網(wǎng)絡(luò)中唯一的數(shù)據(jù)
5.1.2 每個(gè)人都有住址.URL就是類似人的住址.

5.2 URL的格式

5.2.1 協(xié)議頭
http:// 表示傳輸任何數(shù)據(jù)
https:// 表示傳輸任何安全數(shù)據(jù)
ftp:// 表示傳輸大文件
tel:// 表示打電話的 (tel://18510000001)
sms:// 表示發(fā)送短信 (sms://18510000001)
mailto:// 表示發(fā)送郵件 (mailto://zhangjiesharp@163.com)

5.2.2 服務(wù)器地址 / 域名 / 服務(wù)器IP
"open.api.yaolan.com" : 表示向哪個(gè)公司的服務(wù)器獲取數(shù)據(jù)
"www.baidu.com" : 表示向百度公司的服務(wù)器獲取數(shù)據(jù)
服務(wù)器地址 服務(wù)器地址 / 域名 / 服務(wù)器IP : 表示這個(gè)計(jì)算機(jī)在互聯(lián)網(wǎng)中的地址 / 位置的標(biāo)識
"14.215.177.38" : 表示百度服務(wù)器在互聯(lián)網(wǎng)中的IP地址
"www.baidu.com" : "14.215.177.38" 是一一對應(yīng)的
提示 : 域名比四分十進(jìn)制的IP表示法,更加好記憶
為什么通過域名就可以訪問到百度的服務(wù)器? DNS服務(wù)器(域名解析服務(wù)器)會把域名解析成IP地址

5.2.3 數(shù)據(jù)存放的路徑
數(shù)據(jù)存放在數(shù)據(jù)庫中的,數(shù)據(jù)庫是個(gè)硬件設(shè)備,類似電腦的磁盤;
類似于 : 磁盤里面存放數(shù)據(jù)是需要指定路徑的

5.2.4 URL的參數(shù)
參數(shù)就是告訴服務(wù)器我要什么樣的數(shù)據(jù),比如,要幾條數(shù)據(jù)...

6.HTTP協(xié)議

6.1 協(xié)議
6.1.1 協(xié)議概念 : 規(guī)定了請求和響應(yīng)的格式;還規(guī)定了URL的格式;還規(guī)定了請求怎么發(fā),響應(yīng)怎么發(fā);
6.1.2 協(xié)議作用 : 一旦規(guī)定好了請求和響應(yīng)的格式之后,那么服務(wù)器就可以讀懂客戶端的請求;而且客戶端也可以讀懂服務(wù)器的響應(yīng)

6.2 HTTP協(xié)議 : 超文本傳輸協(xié)議;
6.2.1 超文本 : 表示任何數(shù)據(jù)
6.2.2 超文本傳輸協(xié)議 : 表示可以傳輸任何數(shù)據(jù)
6.2.3 比較 : tel:// 只能打電話,不能傳輸超文本數(shù)據(jù)

7.HTTP協(xié)議特點(diǎn)

7.1 簡單 / 快速 / 靈活
7.2 HTTP協(xié)議版本
7.2.1 提示 : HTTP協(xié)議版本的選擇不是客戶端的事情,是服務(wù)決定的.不要瞎操心;
7.2.1 HTTP協(xié)議版本分為
HTTP 0.9 和 HTTP 1.0 "使用非持續(xù)鏈接"

1."非持續(xù)鏈接" : 一次鏈接只能處理一次請求和響應(yīng)
2.兩個(gè)計(jì)算機(jī)之間要想能夠傳輸數(shù)據(jù),必須先建立好鏈接
3.非持續(xù)鏈接,一旦發(fā)送一個(gè)請求,處理一個(gè)響應(yīng),鏈接就"立即斷開"
4.下次如果還要發(fā)送請求,需要再次建立鏈接
5.使用場景 : 對服務(wù)器資源占用要求高的APP
6.好處 : 可以及時(shí)釋放服務(wù)器的鏈接壓力
7.缺點(diǎn) : 每次請求和響應(yīng)之前都要建立鏈接,消耗資源

HTTP 1.1 "使用持續(xù)鏈接"

1."持續(xù)鏈接" : 一次鏈接可以處理多次請求和響應(yīng)
2.兩個(gè)計(jì)算機(jī)之間要想能夠傳輸數(shù)據(jù),必須先建立好鏈接
3.當(dāng)一次請求和響應(yīng)結(jié)束之后,那么這個(gè)"鏈接會持續(xù)一段時(shí)間"
4.在鏈接持續(xù)的時(shí)間內(nèi),可以發(fā)送多次請求和響應(yīng)
5."持續(xù)鏈接遲早還是會斷開的"
6.使用場景 : 對服務(wù)器資源占用要求高的APP
7.好處 : 可以及時(shí)釋放服務(wù)器的鏈接壓力
8.缺點(diǎn) : 每次請求和響應(yīng)之前都要建立鏈接,消耗資源

8.短連接和長連接和心跳包
8.1 短連接 : 包含非持續(xù)鏈接和持續(xù)鏈接
8.1.1 總之會斷開
8.1.2 能夠及時(shí)釋放服務(wù)器資源
8.1.3 讓服務(wù)器能夠?yàn)楦嗟挠脩籼峁┓?wù)

8.2 長連接
8.2.1 一旦建立鏈接就不會"主動(dòng)斷開";除非退出登錄,程序閃退,斷網(wǎng)...才會斷開鏈接
8.2.2 不能及時(shí)釋放服務(wù)器資源;那么就會對服務(wù)器的性能要求很高,要去服務(wù)器具備高并發(fā)性(能夠鏈接更多的用戶)
8.2.3 使用場景 : 需要數(shù)據(jù)及時(shí)到達(dá)的APP(及時(shí)通訊 : 微信,扣扣,陌陌...)

8.3 心跳包
8.3.1 是"檢測長連接"的重要手段
8.3.2 心跳包的發(fā)起者可以是客戶端,可以是服務(wù)器

9.請求和響應(yīng)

9.1 請求
請求行 : "GET / HTTP/1.1" 請求方法 空格 資源路徑 空格 協(xié)議版本
請求頭 : 客戶端告訴服務(wù)器一些額外信息,其中包括服務(wù)器地址(host : 必不可少)/設(shè)備環(huán)境...
請求體(可選) : GET請求是沒有請求體,只有POST請求有請求體

9.2 響應(yīng)
狀態(tài)行(響應(yīng)行) : "HTTP/1.1 200 OK" 協(xié)議版本 空格 狀態(tài)碼 狀態(tài)碼英文描述
響應(yīng)頭 : 服務(wù)器告訴客戶端的額外信息,其中包括服務(wù)器端的版本,服務(wù)器類型,文件在服務(wù)器大小,文件在服務(wù)器類型...
響應(yīng)體 : 客戶端發(fā)送請求的目的;就是保存在服務(wù)器數(shù)據(jù)庫里面的數(shù)據(jù)

10.NSURLConnection的使用

10.1 創(chuàng)建URL
10.2 創(chuàng)建請求 (NSURLRequest / NSMutableURLRequest)
10.3 異步發(fā)送請求,異步獲取數(shù)據(jù)
10.4 "如果獲取到服務(wù)器發(fā)送過來的響應(yīng)體(data : 二進(jìn)制) : 需要把二進(jìn)制反序列化,轉(zhuǎn)成客戶端可以直接使用的OC對象"
10.5 把反序列化之后的數(shù)據(jù)展示到控件上

11.網(wǎng)絡(luò)通信三要素
11.1 通過IP找服務(wù)器,通過端口號找處理請求的進(jìn)程,通過傳輸協(xié)議確定數(shù)據(jù)如何傳輸

12.UDP和TCP傳輸協(xié)議

12.1 UDP(數(shù)據(jù)報(bào)文協(xié)議)
12.1.1 相當(dāng)于廣播,數(shù)據(jù)在傳輸之前你不需要先建立鏈接
12.1.2 非安全的傳輸協(xié)議,容易丟包
12.1.3 流媒體,視頻的實(shí)時(shí)共享

12.2 TCP(數(shù)據(jù)控制協(xié)議)
12.2.1 相當(dāng)于打電話,數(shù)據(jù)在傳輸之前,計(jì)算機(jī)之間一定要先建立好鏈接
12.2.2 安全的傳輸協(xié)議,不容易丟包
12.2.3 使用場景,適用絕大多數(shù)APP
12.2.4 只要你的協(xié)議是HTTP / HTTPS協(xié)議,就表示你選擇的傳輸協(xié)議就是TCP

13.Socket開發(fā)體驗(yàn)

13.1 如果客戶端使用Socket進(jìn)行網(wǎng)絡(luò)開發(fā),需要做那幾件事情?
創(chuàng)建客戶端Socket
客戶端Socket鏈接到服務(wù)器端Socket
客戶端Socket向服務(wù)器Socket發(fā)送請求
客戶端Socket接收服務(wù)器Socket發(fā)送的響應(yīng)
關(guān)閉客戶端Socket

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.創(chuàng)建客戶端Socket
    /**
     參數(shù)
     參數(shù)1 : domain,協(xié)議域/協(xié)議簇,AF_INET(IPV4的網(wǎng)絡(luò)開發(fā))
     參數(shù)2 : type,Socket類型,SOCK_STREAM(TCP)/SOCK_DGRAM(UDP,報(bào)文)
     參數(shù)3 : protocol,IPPROTO_TCP,協(xié)議,如果輸入0,可以根據(jù)第二個(gè)參數(shù),自動(dòng)選擇協(xié)議
     提示 : SOCK_STREAM 表示請求是HTTP請求
     
     返回值
     int類型,如果 > 0 就表示成功,返回socket
     clientSocket : 就是套接字描述符
     */
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket > 0) {
        NSLog(@"創(chuàng)建客戶端Socket成功");
    }
    
    // 2.客戶端Socket連接到服務(wù)器Socket
    /**
     參數(shù)
     參數(shù)1 :  客戶端socket / 套接字描述符
     參數(shù)2 :  指向數(shù)據(jù)結(jié)構(gòu)sockaddr的指針,其中包括目的端口和IP地址
     參數(shù)3 :  結(jié)構(gòu)體數(shù)據(jù)長度
     
     返回值 : int類型,返回0表示成功;反之,失敗;
     */
    // 創(chuàng)建指向sockaddr_in的指針;這個(gè)結(jié)構(gòu)體里面封裝了端口號和IP
    struct sockaddr_in addr;
    // 設(shè)置協(xié)議域
    addr.sin_family = AF_INET;
    // 設(shè)置端口號
    addr.sin_port=htons(80);
    // 指定目標(biāo)計(jì)算機(jī)的IP
    addr.sin_addr.s_addr = inet_addr("14.215.177.37");
    
    int isConnected = connect(clientSocket, (const struct sockaddr *)&addr, sizeof(addr));
    if (isConnected == 0) {
        NSLog(@"客戶端Socket鏈接到服務(wù)器Socket成功");
    }
    
    // 3.客戶端Socket向服務(wù)器Socket發(fā)送請求
    /**
     參數(shù)
     參數(shù)1 : 客戶端socket
     參數(shù)2 : 發(fā)送內(nèi)容地址 void * == id
     參數(shù)3 : 發(fā)送內(nèi)容長度
     參數(shù)4 : 發(fā)送方式標(biāo)志,一般為0
     
     返回值
     如果成功,則返回發(fā)送的字節(jié)數(shù),失敗則返回SOCKET_ERROR
     */
    
    // 請求的內(nèi)容 : 必須嚴(yán)格按照HTTP協(xié)議的規(guī)定去寫
    NSString *sendMsg = @"GET / HTTP/1.1\r\n"
                        "Host: www.baidu.com\r\n"
                        "User-Agent: iphone\r\n"
                        "Connection: close\r\n\r\n"
                        ;
    
    // Socket把請求信息,發(fā)送給服務(wù)器
    ssize_t sendLen = send(clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0);
    NSLog(@"%ld",sendLen);
    
    // 4.客戶端Socket接收服務(wù)器Socket發(fā)送的響應(yīng)
    /**
     參數(shù)
     參數(shù)1 : 客戶端socket
     參數(shù)2 : 接收內(nèi)容的容器的地址
     參數(shù)3 : 接收內(nèi)容緩存區(qū)長度
     參數(shù)4 : 接收方式,0表示阻塞,必須等待服務(wù)器返回?cái)?shù)據(jù),才執(zhí)行這個(gè)函數(shù),服務(wù)器發(fā)一次數(shù)據(jù),就執(zhí)行一次
     
     返回值
     如果成功,則返回接收的字節(jié)數(shù),失敗則返回SOCKET_ERROR
     */
    
    // 定義字符暫存區(qū) : 定義一個(gè)專門接收字符的數(shù)組,數(shù)組名就是數(shù)組的地址
    u_int8_t buffer[1024];
    // 先定義非0,保證第一次可以進(jìn)入循環(huán),一定要是負(fù)數(shù),因?yàn)榉?wù)器給你發(fā)送的字節(jié)數(shù)是正式
    ssize_t recvLen = -1;
    
    // 定義可變data,拼接buffer
    NSMutableData *dataM = [NSMutableData data];
    
    while (recvLen) {
        // recv 默認(rèn)只接收一次,如果需要把完整的數(shù)據(jù)接收完,就需要在循環(huán)里面接收
        recvLen = recv(clientSocket, buffer, sizeof(buffer), 0);
        NSLog(@"%ld",recvLen);
        
        // 循環(huán)拼接buffer
        [dataM appendBytes:buffer length:recvLen];
    }
    
    // 字符串的反序列化
    NSString *html = [[NSString alloc] initWithData:dataM encoding:NSUTF8StringEncoding];
    NSLog(@"%@",html);
    
    // 5.關(guān)閉客戶端Socket
    close(clientSocket);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容