一次網(wǎng)絡(luò)請(qǐng)求的流程:
域名解析 -----> TCP的三次握手 -----> 建立TCP連接后發(fā)起HTTP請(qǐng)求 -----> 服務(wù)器響應(yīng)HTTP請(qǐng)求 ----->( 解析返回的數(shù)據(jù)然后對(duì)頁面進(jìn)行渲染并呈現(xiàn)給用戶) -----> 四次揮手結(jié)束連接。通過本片文章的學(xué)習(xí),你講學(xué)會(huì):
1.計(jì)算機(jī)的網(wǎng)絡(luò)體系結(jié)構(gòu)
2.Http相關(guān)以及get請(qǐng)求和post請(qǐng)求
3.TCP的連接建立和斷開以及TCP和UDP的區(qū)別
4.Socket基本使用
一.計(jì)算機(jī)的網(wǎng)絡(luò)體系結(jié)構(gòu)
計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)分為3種:
OSI體系結(jié)構(gòu):概念清楚 & 理念完整,但復(fù)雜 & 不實(shí)用
TCP / IP體系結(jié)構(gòu):含了一系列構(gòu)成互聯(lián)網(wǎng)基礎(chǔ)的網(wǎng)絡(luò)協(xié)議,是Internet的核心協(xié)議 & 被廣泛應(yīng)用于局域網(wǎng) 和 廣域網(wǎng)
五層體系結(jié)構(gòu):融合了OSI 與 TCP / IP的體系結(jié)構(gòu),目的是為了學(xué)習(xí) 和計(jì)算機(jī)原理
3種計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)如圖所示:

五層體系結(jié)構(gòu)各自負(fù)責(zé)什么呢?
應(yīng)用層:如http協(xié)議,它實(shí)際上是定義了如何包裝和解析數(shù)據(jù),應(yīng)用層是http協(xié)議的話,則會(huì)按照協(xié)議規(guī)定包裝數(shù)據(jù),如按照請(qǐng)求行、請(qǐng)求頭、請(qǐng)求體包裝,包裝好數(shù)據(jù)后將數(shù)據(jù)傳至運(yùn)輸層。
運(yùn)輸層:運(yùn)輸層有TCP和UDP兩種協(xié)議,分別對(duì)應(yīng)可靠的運(yùn)輸和不可靠的運(yùn)輸,如TCP因?yàn)橐峁┛煽康膫鬏?,所以?nèi)部要解決如何建立連接、如何保證傳輸是可靠的不丟數(shù)據(jù)、如何調(diào)節(jié)流量控制和擁塞控制。關(guān)于這一層,我們平常一般都是和Socket打交道,Socket是一組封裝的編程調(diào)用接口,通過它,我們就能操作TCP、UDP進(jìn)行連接的建立等。我們平常使用Socket進(jìn)行連接建立的時(shí)候,一般都要指定端口號(hào),所以這一層指定了把數(shù)據(jù)送到對(duì)應(yīng)的端口號(hào)。
網(wǎng)絡(luò)層:這一層IP協(xié)議,以及一些路由選擇協(xié)議等等,所以這一層的指定了數(shù)據(jù)要傳輸?shù)侥膫€(gè)IP地址。中間涉及到一些最優(yōu)線路,路由選擇算法等等。
鏈路層:負(fù)責(zé)把IP地址解析為MAC地址,即硬件地址,這樣就找到了對(duì)應(yīng)的唯一的機(jī)器。
物理層:這一層就是最底層了,提供二進(jìn)制流傳輸服務(wù),也就是也就是真正開始通過傳輸介質(zhì)(有線、無線)開始進(jìn)行數(shù)據(jù)的傳輸了。
二.Http相關(guān)以及get請(qǐng)求和post請(qǐng)求
HTTP基于TCP的應(yīng)用層協(xié)議。
1.http無連接無狀態(tài)的
無連接:不是說不需要連接,Http協(xié)議只是一個(gè)應(yīng)用層協(xié)議,最終還是要靠運(yùn)輸層的如TCP協(xié)議向上提供的服務(wù)進(jìn)行連接。無連接的含義是http約定了每次連接只處理一個(gè)請(qǐng)求,一次請(qǐng)求完成后就斷開連接,這樣主要是為了緩解服務(wù)器的壓力,減小連接對(duì)服務(wù)器資源的占用。
無狀態(tài):指每個(gè)請(qǐng)求之間都是獨(dú)立的,對(duì)于之前的請(qǐng)求事務(wù)沒有記憶的能力。所以就出現(xiàn)了像Cookie這種,用來保存一些狀態(tài)的東西。
2.請(qǐng)求報(bào)文和響應(yīng)報(bào)文
請(qǐng)求報(bào)文和響應(yīng)報(bào)文的格式如圖所示:


3.HTTPS
我們都知道Https保證了我們數(shù)據(jù)傳輸?shù)陌踩?,Https=Http+Ssl,之所以能保證安全主要的原理就是利用了非對(duì)稱加密算法,平常用的對(duì)稱加密算法之所以不安全,是因?yàn)殡p方是用統(tǒng)一的密匙進(jìn)行加密解密的,只要雙方任意一方泄漏了密匙,那么其他人就可以利用密匙解密數(shù)據(jù)。而非對(duì)稱加密算法之所以能實(shí)現(xiàn)安全傳輸?shù)暮诵木A就是: 公鑰加密的信息只能用私鑰解開,私鑰加密的信息只能被公鑰解開。
HTTP中GET和POST請(qǐng)求的區(qū)別:
GET和POST本質(zhì)上就是TCP鏈接,并無差別。但是由于HTTP的規(guī)定和瀏覽器/服務(wù)器的限制,導(dǎo)致他們?cè)趹?yīng)用過程中體現(xiàn)出一些不同。
1.GET在瀏覽器回退時(shí)是無害的,而POST會(huì)再次提交請(qǐng)求。
2.GET請(qǐng)求會(huì)被瀏覽器主動(dòng)cache,而POST不會(huì),除非手動(dòng)設(shè)置。
3.GET請(qǐng)求只能進(jìn)行url編碼,而POST支持多種編碼方式。
4.GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會(huì)被保留。
5.GET請(qǐng)求在URL中傳送的參數(shù)是有長度限制的,而POST沒有。
6.GET比POST更不安全,因?yàn)閰?shù)直接暴露在URL上,所以不能用來傳遞敏感信息。
7.GET參數(shù)通過URL傳遞,POST放在Request body中。
三.TCP和UDP
TCP
TCP面向連接,提供可靠的數(shù)據(jù)傳輸,屬于傳輸層通信協(xié)議,基于TCP的應(yīng)用層協(xié)議有HTTP、SMTP、FTP、Telnet 和 POP3 。
1.三次握手建立連接如圖所示:

第一次:發(fā)送SNY=1表示此次握手是請(qǐng)求建立連接的,然后seq生成一個(gè)客戶端的隨機(jī)數(shù)X
第二次:發(fā)送SNY=1,ACK=1表示是回復(fù)請(qǐng)求建立連接的,然后ack=客戶端的seq+1(這樣客戶端收到后就能確認(rèn)是之前想要連接的那個(gè)服務(wù)端),然后把服務(wù)端也生成一個(gè)代表自己的隨機(jī)數(shù)seq=Y發(fā)給客戶端。
第三次:ACK=1。 seq=客戶端隨機(jī)數(shù)+1,ack=服務(wù)端隨機(jī)數(shù)+1(這樣服務(wù)端就知道是剛剛那個(gè)客戶端了)
2.連接的建立為什么需要三次:
第一次握手,C端發(fā)了個(gè)連接請(qǐng)求消息到S端,S端收到后S端就知道自己與C端是可以連接成功的,但是C端此時(shí)并不知道S端是否接收到這個(gè)消息,所以S端接收到消息后得應(yīng)答,C端得到S端的回復(fù)后,才能確定自己與S端是可以連接上的,這就是第二次握手。C端只有確定了自己能與S端連接上才能開始發(fā)數(shù)據(jù)。所以兩次握手肯定是最基本的。假設(shè)一下如果沒有第三次握手,而是兩次握手后我們就認(rèn)為連接建立,那么會(huì)發(fā)生什么?
比如一個(gè)情況:C端發(fā)出去的第一個(gè)網(wǎng)絡(luò)連接請(qǐng)求由于某些原因在網(wǎng)絡(luò)節(jié)點(diǎn)中滯留了,導(dǎo)致延遲,直到連接釋放的某個(gè)時(shí)間點(diǎn)才到達(dá)S端,這是一個(gè)早已失效的報(bào)文,但是此時(shí)S端仍然認(rèn)為這是C端的建立連接請(qǐng)求第一次握手,于是S端回應(yīng)了C端,第二次握手。如果只有兩次握手,那么到這里,連接就建立了,但是此時(shí)C端并沒有任何數(shù)據(jù)要發(fā)送,而S端就會(huì)傻傻的等待著,造成很大的資源浪費(fèi)。所以需要第三次握手,只有C端再次回應(yīng)一下,就可以避免這種情況。第三次握手是為了防止已經(jīng)失效的連接請(qǐng)求報(bào)文段突然又傳到服務(wù)端,因而產(chǎn)生錯(cuò)誤
3.四次握手?jǐn)嚅_連接如圖所示:

4.為什么斷開比連接多一次
可以看到這里服務(wù)端的ACK(回復(fù)客戶端)和FIN(終止)消息并不是同時(shí)發(fā)出的,而是先ACK,然后再FIN,這也很好理解,當(dāng)客戶端要求斷開連接時(shí),此時(shí)服務(wù)端可能還有未發(fā)送完的數(shù)據(jù),所以先ACK,然后等數(shù)據(jù)發(fā)送完再FIN。這樣就變成了四次握手了。
UDP
UDP 提供無連接的、盡最大努力的數(shù)據(jù)傳輸服務(wù)(不保證數(shù)據(jù)傳輸?shù)目煽啃裕?,提供無連接的、盡最大努力的數(shù)據(jù)傳輸服務(wù)(不保證數(shù)據(jù)傳輸?shù)目煽啃裕?,UDP是面向報(bào)文的,UDP沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)的擁塞不會(huì)使源主機(jī)發(fā)送速率降低,UDP支持一對(duì)一、一對(duì)多、多對(duì)一、多對(duì)多的交互通信,UDP的首部開銷小。其數(shù)據(jù)傳輸?shù)膯挝皇怯脩魯?shù)據(jù)報(bào)。
TCP和UDP區(qū)別:
1.TCP面向連接(如打電話要先撥號(hào)建立連接);UDP是無連接的,即發(fā)送數(shù)據(jù)之前不需要建立連接
2.TCP提供可靠的服務(wù)。也就是說,通過TCP連接傳送的數(shù)據(jù),無差錯(cuò),不丟失,不重復(fù),且按序到達(dá);UDP盡最大努力交付,即不保 證可靠交付
3.TCP面向字節(jié)流,實(shí)際上是TCP把數(shù)據(jù)看成一連串無結(jié)構(gòu)的字節(jié)流;UDP是面向報(bào)文的 UDP沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)擁塞不會(huì)使源主機(jī)的發(fā)送速率降低(對(duì)實(shí)時(shí)應(yīng)用很有用,如IP電話,實(shí)時(shí)視頻會(huì)議等)
4.、每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對(duì)一,一對(duì)多,多對(duì)一和多對(duì)多的交互通信
5.TCP首部開銷20字節(jié);UDP的首部開銷小,只有8個(gè)字節(jié)
6.TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道
四.Socket基本使用
1.Socket是什么
Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設(shè)計(jì)模式中,Socket其實(shí)就是一個(gè)門面模式,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對(duì)用戶來說,一組簡(jiǎn)單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。它的位置如下圖所示:

2.socket的基本操作
socket是“open—write/read—close”模式的一種實(shí)現(xiàn),那么socket就提供了這些操作對(duì)應(yīng)的函數(shù)接口。
我們通過socket在客戶端發(fā)送和接收服務(wù)端信息:
public class SocketClient {
public static void main(String args[]) throws Exception {
// 要連接的服務(wù)端IP地址和端口
String host = "127.0.0.1";
int port = 55533;
// 與服務(wù)端建立連接
Socket socket = new Socket(host, port);
// 發(fā)送,建立連接后獲得輸出流
OutputStream outputStream = socket.getOutputStream();
String message = "你好 yiwangzhibujian";
socket.getOutputStream().write(message.getBytes("UTF-8"));
//通過shutdownOutput高速服務(wù)器已經(jīng)發(fā)送完數(shù)據(jù),后續(xù)只能接受數(shù)據(jù)
socket.shutdownOutput();
//讀取
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
//注意指定編碼格式,發(fā)送方和接收方一定要統(tǒng)一,建議使用UTF-8
sb.append(new String(bytes, 0, len,"UTF-8"));
}
System.out.println("get message from server: " + sb);
inputStream.close();
outputStream.close();
socket.close();
}
}
五.總結(jié)
以上就是關(guān)于Android網(wǎng)絡(luò)的相關(guān)知識(shí)點(diǎn),如有不足或者錯(cuò)誤的地方請(qǐng)?jiān)谙路街刚?。我們需要多看更需要多寫,只有不斷學(xué)習(xí),不斷進(jìn)步才能不被淘汰。