計(jì)算機(jī)網(wǎng)絡(luò)太難?了解這一篇就夠了
計(jì)算機(jī)網(wǎng)絡(luò)、計(jì)算機(jī)操作系統(tǒng)這兩個(gè)“兄弟”是所有開發(fā)崗位都需要“結(jié)拜”的,不管你是 Java、C++還是測試。對于后端開發(fā)的童鞋來說,計(jì)算機(jī)網(wǎng)絡(luò)的重要性不亞于語言基礎(chǔ),畢竟平時(shí)開發(fā)經(jīng)常會和網(wǎng)絡(luò)打交道,比如:抓個(gè)包等等。所以對這一塊知識點(diǎn)的準(zhǔn)備還是要抱著敬畏之心,不要放過任何一個(gè)漏網(wǎng)之題。下面創(chuàng)新互聯(lián)分享下我的學(xué)習(xí)過程:
1. 看書:對于計(jì)算機(jī)比較基礎(chǔ)的模塊,我都是比較推薦找一本經(jīng)典的書籍來好好學(xué)習(xí)下,不可以只看面經(jīng)就去面試了。我一共看了兩本書:湯小丹的《計(jì)算機(jī)操作系統(tǒng)》和《圖解HTTP》。《計(jì)算機(jī)操作系統(tǒng)》是教科書,所以知識點(diǎn)相對比較基礎(chǔ),覆蓋范圍也比較廣,非科班的學(xué)生還是很有必要看一看的?!秷D解HTTP》這本書用很多插圖將一些知識點(diǎn)講的通俗易懂,看起來也很快,還是比較推薦的。
2. 做筆記:計(jì)算機(jī)網(wǎng)絡(luò)的知識點(diǎn)還是比較多的,需要看書的時(shí)候做好筆記,方便復(fù)習(xí)。而且做筆記的時(shí)候可以就這個(gè)知識點(diǎn)去百度下,看看有沒有自己遺漏的點(diǎn),再給補(bǔ)充進(jìn)來。在這里說下,我為什么一直強(qiáng)調(diào)做筆記?好處 1:做筆記是第 1 次你對書中的知識點(diǎn)的回顧,加深記憶;好處 2:而且如果你是發(fā)表在公關(guān)社區(qū)的肯定要保證大限度的正確性,就需要再去看看這個(gè)知識點(diǎn),核對下自己是否有理解偏差和遺漏等,這樣就完成了知識點(diǎn)的深挖;好處3:正在到面試復(fù)習(xí)的時(shí)候,你是不太可能重新看一本書的,那么筆記就顯得很重要了,自己做的筆記,復(fù)習(xí)起來很快,而且最好在筆記里能有一些自己區(qū)別于面經(jīng)的理解。
3. 看面經(jīng):經(jīng)常刷一刷???,看看對于計(jì)算機(jī)網(wǎng)絡(luò),面試官們都是怎么問的?很多問題你可能會,但是不懂面試官的問法,也會回答不上來;問到的題目自己是否準(zhǔn)備了?而且對于計(jì)算機(jī)網(wǎng)絡(luò)和計(jì)算機(jī)操作系統(tǒng)會因?yàn)楣竞蛵徫坏牟煌兴鶄?cè)重的,多看看面經(jīng)就會發(fā)現(xiàn)還是有一點(diǎn)規(guī)律的,但是這都不是絕對的,最后還要看面你的面試官的喜好。
學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)時(shí)我們一般采用折中的辦法,也就是中和 OSI 和 TCP/IP 的優(yōu)點(diǎn),采用一種只有五層協(xié)議的體系結(jié)構(gòu),這樣既簡潔又能將概念闡述清楚。
應(yīng)用層(application-layer)的任務(wù)是通過應(yīng)用進(jìn)程間的交互來完成特定網(wǎng)絡(luò)應(yīng)用。應(yīng)用層協(xié)議定義的是應(yīng)用進(jìn)程(進(jìn)程:
主機(jī)中正在運(yùn)行的程序)間的通信和交互的規(guī)則。對于不同的網(wǎng)絡(luò)應(yīng)用需要不同的應(yīng)用層協(xié)議。在互聯(lián)網(wǎng)中應(yīng)用層協(xié)議很多,如
域名系統(tǒng) DNS,支持萬維網(wǎng)應(yīng)用的 HTTP 協(xié)議,支持電子郵件的 SMTP 協(xié)議等等。我們把應(yīng)用層交互的數(shù)據(jù)單元稱為報(bào)文。
運(yùn)輸層(transport layer)的主要任務(wù)就是負(fù)責(zé)向兩臺
主機(jī)進(jìn)程之間的通信提供通用的數(shù)據(jù)傳輸服務(wù)。應(yīng)用進(jìn)程利用該服務(wù)傳送應(yīng)用層報(bào)文?!巴ㄓ玫摹笔侵覆⒉会槍δ骋粋€(gè)特定的網(wǎng)絡(luò)應(yīng)用,而是多種應(yīng)用可以使用同一個(gè)運(yùn)輸層服務(wù)。
由于一臺
主機(jī)可同時(shí)運(yùn)行多個(gè)線程,因此運(yùn)輸層有復(fù)用和分用的功能。所謂復(fù)用就是指多個(gè)應(yīng)用層進(jìn)程可同時(shí)使用下面運(yùn)輸層的服務(wù),分用和復(fù)用相反,是運(yùn)輸層把收到的信息分別交付上面應(yīng)用層中的相應(yīng)進(jìn)程。
在計(jì)算機(jī)網(wǎng)絡(luò)中進(jìn)行通信的兩個(gè)計(jì)算機(jī)之間可能會經(jīng)過很多個(gè)數(shù)據(jù)鏈路,也可能還要經(jīng)過很多通信子網(wǎng)。網(wǎng)絡(luò)層的任務(wù)就是選擇合適的網(wǎng)間路由和交換結(jié)點(diǎn), 確保數(shù)據(jù)及時(shí)傳送。在發(fā)送數(shù)據(jù)時(shí),網(wǎng)絡(luò)層把運(yùn)輸層產(chǎn)生的報(bào)文段或用戶數(shù)據(jù)報(bào)封裝成分組和包進(jìn)行傳送。在 TCP / IP 體系結(jié)構(gòu)中,由于網(wǎng)絡(luò)層使用 IP 協(xié)議,因此分組也叫 IP 數(shù)據(jù)報(bào),簡稱數(shù)據(jù)報(bào)。
數(shù)據(jù)鏈路層(data link layer)通常簡稱為鏈路層。兩臺
主機(jī)之間的數(shù)據(jù)傳輸,總是在一段一段的鏈路上傳送的,這就需要使用專門的鏈路層的協(xié)議。在兩個(gè)相鄰節(jié)點(diǎn)之間傳送數(shù)據(jù)時(shí),數(shù)據(jù)鏈路層將網(wǎng)絡(luò)層交下來的 IP 數(shù)據(jù)報(bào)組裝成幀,在兩個(gè)相鄰節(jié)點(diǎn)間的鏈路上傳送幀。每一幀包括數(shù)據(jù)和必要的控制信息(如:同步信息,地址信息,差錯(cuò)控制等)。
在接收數(shù)據(jù)時(shí),控制信息使接收端能夠知道一個(gè)幀從哪個(gè)比特開始和到哪個(gè)比特結(jié)束。這樣,數(shù)據(jù)鏈路層在收到一個(gè)幀后,就可從中提出數(shù)據(jù)部分,上交給網(wǎng)絡(luò)層??刂菩畔⑦€使接收端能夠檢測到所收到的幀中有無差錯(cuò)。如果發(fā)現(xiàn)差錯(cuò),數(shù)據(jù)鏈路層就簡單地丟棄這個(gè)出了差錯(cuò)的幀,以避免繼續(xù)在網(wǎng)絡(luò)中傳送下去白白浪費(fèi)網(wǎng)絡(luò)資源。如果需要改正數(shù)據(jù)在鏈路層傳輸時(shí)出現(xiàn)差錯(cuò)(這就是說,數(shù)據(jù)鏈路層不僅要檢錯(cuò),而且還要糾錯(cuò)),那么就要采用可靠性傳輸協(xié)議來糾正出現(xiàn)的差錯(cuò)。這種方法會使鏈路層的協(xié)議復(fù)雜些。
在物理層上所傳送的數(shù)據(jù)單位是比特。物理層(physical layer)的作用是實(shí)現(xiàn)相鄰計(jì)算機(jī)節(jié)點(diǎn)之間比特流的透明傳送,盡可能屏蔽掉具體傳輸介質(zhì)和物理設(shè)備的差異。使其上面的數(shù)據(jù)鏈路層不必考慮網(wǎng)絡(luò)的具體傳輸介質(zhì)是什么?!巴该鱾魉捅忍亓鳌北硎窘?jīng)實(shí)際電路傳送后的比特流沒有發(fā)生變化,對傳送的比特流來說,這個(gè)電路好像是看不見的。
計(jì)算機(jī)五層網(wǎng)絡(luò)體系中涉及的協(xié)議非常多,下面就常用的做了列舉:
計(jì)算機(jī)網(wǎng)絡(luò)太難?了解這一篇就夠了
網(wǎng)絡(luò)層的 ARP 協(xié)議完成了 IP 地址與物理地址的映射。首先,每臺
主機(jī)都會在自己的 ARP 緩沖區(qū)中建立一個(gè) ARP 列表,以表示 IP 地址和 MAC 地址的對應(yīng)關(guān)系。當(dāng)源
主機(jī)需要將一個(gè)數(shù)據(jù)包要發(fā)送到目的
主機(jī)時(shí),會首先檢查自己 ARP 列表中是否存在該 IP 地址對應(yīng)的 MAC 地址:如果有,就直接將數(shù)據(jù)包發(fā)送到這個(gè) MAC 地址;如果沒有,就向本地網(wǎng)段發(fā)起一個(gè) ARP 請求的廣播包,查詢此目的
主機(jī)對應(yīng)的 MAC 地址。
此 ARP 請求數(shù)據(jù)包里包括源
主機(jī)的 IP 地址、硬件地址、以及目的
主機(jī)的 IP 地址。網(wǎng)絡(luò)中所有的
主機(jī)收到這個(gè) ARP 請求后,會檢查數(shù)據(jù)包中的目的 IP 是否和自己的 IP 地址一致。如果不相同就忽略此數(shù)據(jù)包;如果相同,該
主機(jī)首先將發(fā)送端的 MAC 地址和 IP 地址添加到自己的 ARP 列表中,如果 ARP 表中已經(jīng)存在該 IP 的信息,則將其覆蓋,然后給源
主機(jī)發(fā)送一個(gè) ARP 響應(yīng)數(shù)據(jù)包,告訴對方自己是它需要查找的 MAC 地址;源
主機(jī)收到這個(gè) ARP 響應(yīng)數(shù)據(jù)包后,將得到的目的
主機(jī)的 IP 地址和 MAC 地址添加到自己的 ARP 列表中,并利用此信息開始數(shù)據(jù)的傳輸。如果源
主機(jī)一直沒有收到 ARP 響應(yīng)數(shù)據(jù)包,表示 ARP 查詢失敗。
IP 地址是指互聯(lián)網(wǎng)協(xié)議地址,是 IP 協(xié)議提供的一種統(tǒng)一的地址格式,它為互聯(lián)網(wǎng)上的每一個(gè)網(wǎng)絡(luò)和每一臺
主機(jī)分配一個(gè)邏輯地址,以此來屏蔽物理地址的差異。IP 地址編址方案將 IP 地址
空間劃分為 A、B、C、D、E 五類,其中 A、B、C 是基本類,D、E 類作為多播和保留使用,為特殊地址。
每個(gè) IP 地址包括兩個(gè)標(biāo)識碼(ID),即網(wǎng)絡(luò) ID 和
主機(jī) ID。同一個(gè)物理網(wǎng)絡(luò)上的所有
主機(jī)都使用同一個(gè)網(wǎng)絡(luò) ID,網(wǎng)絡(luò)上的一個(gè)
主機(jī)(包括網(wǎng)絡(luò)上工作站,服務(wù)器和路由器等)有一個(gè)
主機(jī) ID 與其對應(yīng)。A~E 類地址的特點(diǎn)如下:
A 類地址:以 0 開頭,第一個(gè)字節(jié)范圍:0~127;
B 類地址:以 10 開頭,第一個(gè)字節(jié)范圍:128~191;
C 類地址:以 110 開頭,第一個(gè)字節(jié)范圍:192~223;
D 類地址:以 1110 開頭,第一個(gè)字節(jié)范圍為 224~239;
E 類地址:以 1111 開頭,保留地址
1. TCP 是面向連接的。(就好像打電話一樣,通話前需要先撥號建立連接,通話結(jié)束后要掛機(jī)釋放連接);
2. 每一條 TCP 連接只能有兩個(gè)端點(diǎn),每一條 TCP 連接只能是點(diǎn)對點(diǎn)的(一對一);
3. TCP 提供可靠交付的服務(wù)。通過 TCP 連接傳送的數(shù)據(jù),無差錯(cuò)、不丟失、不重復(fù)、并且按序到達(dá);
4. TCP 提供全雙工通信。TCP 允許通信雙方的應(yīng)用進(jìn)程在任何時(shí)候都能發(fā)送數(shù)據(jù)。TCP 連接的兩端都設(shè)有發(fā)送緩存和接收緩存,用來臨時(shí)存放雙方通信的數(shù)據(jù);
5. 面向字節(jié)流。TCP 中的“流”(Stream)指的是流入進(jìn)程或從進(jìn)程流出的字節(jié)序列?!懊嫦蜃止?jié)流”的含義是:雖然應(yīng)用程序和 TCP 的交互是一次一個(gè)數(shù)據(jù)塊(大小不等),但 TCP 把應(yīng)用程序交下來的數(shù)據(jù)僅僅看成是一連串的無結(jié)構(gòu)的字節(jié)流。
1. UDP 是無連接的;
2. UDP 使用盡大努力交付,即不保證可靠交付,因此
主機(jī)不需要維持復(fù)雜的鏈接狀態(tài)(這里面有許多參數(shù));
3. UDP 是面向報(bào)文的;
4. UDP 沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)擁塞不會使源
主機(jī)的發(fā)送速率降低(對實(shí)時(shí)應(yīng)用很有用,如 直播,實(shí)時(shí)視頻會議等);
5. UDP 支持一對一、一對多、多對一和多對多的交互通信;
6. UDP 的首部開銷小,只有 8 個(gè)字節(jié),比 TCP 的 20 個(gè)字節(jié)的首部要短。
TCP 提供面向連接的服務(wù)。在傳送數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳送結(jié)束后要釋放連接。TCP 不提供廣播或多播服務(wù)。由于 TCP 要提供可靠的,面向連接的運(yùn)輸服務(wù)(TCP 的可靠體現(xiàn)在 TCP 在傳遞數(shù)據(jù)之前,會有三次握手來建立連接,而且在數(shù)據(jù)傳遞時(shí),有確認(rèn)、窗口、重傳、擁塞控制機(jī)制,在數(shù)據(jù)傳完后,還會斷開連接用來節(jié)約系統(tǒng)資源),這難以避免增加了許多開銷,如確認(rèn),流量控制,計(jì)時(shí)器以及連接管理等。這不僅使協(xié)議數(shù)據(jù)單元的首部增大很多,還要占用許多處理機(jī)資源。
UDP 在傳送數(shù)據(jù)之前不需要先建立連接,遠(yuǎn)地
主機(jī)在收到 UDP 報(bào)文后,不需要給出任何確認(rèn)。雖然 UDP 不提供可靠交付,但在某些情況下 UDP 確是一種最有效的工作方式(一般用于即時(shí)通信),比如:QQ 語音、 QQ 視頻 、直播等等。
FTP:定義了文件傳輸協(xié)議,使用 21 端口。常說某某計(jì)算機(jī)開了 FTP 服務(wù)便是啟動(dòng)了文件傳輸服務(wù)。下載文件,上傳主頁,都要用到 FTP 服務(wù)。
Telnet:它是一種用于遠(yuǎn)程登陸的端口,用戶可以以自己的身份遠(yuǎn)程連接到計(jì)算機(jī)上,通過這種端口可以提供一種基于 DOS 模式下的通信服務(wù)。如以前的 BBS 是-純字符界面的,支持 BBS 的服務(wù)器將 23 端口打開,對外提供服務(wù)。
SMTP:定義了簡單郵件傳送協(xié)議,現(xiàn)在很多郵件服務(wù)器都用的是這個(gè)協(xié)議,用于發(fā)送郵件。如常見的免費(fèi)郵件服務(wù)中用的就是這個(gè)郵件服務(wù)端口,所以在電子郵件設(shè)置-中??吹接羞@么 SMTP 端口設(shè)置這個(gè)欄,服務(wù)器開放的是 25 號端口。
POP3:它是和 SMTP 對應(yīng),POP3 用于接收郵件。通常情況下,POP3 協(xié)議所用的是 110 端口。也是說,只要你有相應(yīng)的使用 POP3 協(xié)議的程序(例如 Fo-xmail 或 Outlook),就可以不以 Web 方式登陸進(jìn)
郵箱界面,直接用郵件程序就可以收到郵件(如是163
郵箱就沒有必要先進(jìn)入網(wǎng)易網(wǎng)站,再進(jìn)入自己的郵-箱來收信)。
HTTP:從 Web 服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。
DNS:用于
域名解析服務(wù),將
域名地址轉(zhuǎn)換為 IP 地址。DNS 用的是 53 號端口。
SNMP:簡單網(wǎng)絡(luò)管理協(xié)議,使用 161 號端口,是用來管理網(wǎng)絡(luò)設(shè)備的。由于網(wǎng)絡(luò)設(shè)備很多,無連接的服務(wù)就體現(xiàn)出其優(yōu)勢。
TFTP(Trival File Transfer Protocal):簡單文件傳輸協(xié)議,該協(xié)議在熟知端口 69 上使用 UDP 服務(wù)。
TCP 建立連接的過程叫做握手,握手需要在客戶和服務(wù)器之間交換三個(gè) TCP 報(bào)文段。
計(jì)算機(jī)網(wǎng)絡(luò)太難?了解這一篇就夠了
最初客戶端和服務(wù)端都處于 CLOSED(關(guān)閉) 狀態(tài)。本例中 A(Client) 主動(dòng)打開連接,B(Server) 被動(dòng)打開連接。
一開始,B 的 TCP 服務(wù)器進(jìn)程首先創(chuàng)建傳輸控制塊TCB,準(zhǔn)備接受客戶端進(jìn)程的連接請求。然后服務(wù)端進(jìn)程就處于 LISTEN(監(jiān)聽) 狀態(tài),等待客戶端的連接請求。如有,立即作出響應(yīng)。
第一次握手:A 的 TCP 客戶端進(jìn)程也是首先創(chuàng)建傳輸控制塊 TCB。然后,在打算建立 TCP 連接時(shí),向 B 發(fā)出連接請求報(bào)文段,這時(shí)首部中的同步位 SYN=1,同時(shí)選擇一個(gè)初始序號 seq = x。TCP 規(guī)定,SYN 報(bào)文段(即 SYN = 1 的報(bào)文段)不能攜帶數(shù)據(jù),但要消耗掉一個(gè)序號。這時(shí),TCP 客戶進(jìn)程進(jìn)入 SYN-SENT(同步已發(fā)送)狀態(tài)。
第二次握手:B 收到連接請求報(bào)文后,如果同意建立連接,則向 A 發(fā)送確認(rèn)。在確認(rèn)報(bào)文段中應(yīng)把 SYN 位和 ACK 位都置 1,確認(rèn)號是 ack = x + 1,同時(shí)也為自己選擇一個(gè)初始序號 seq = y。請注意,這個(gè)報(bào)文段也不能攜帶數(shù)據(jù),但同樣要消耗掉一個(gè)序號。這時(shí) TCP 服務(wù)端進(jìn)程進(jìn)入 SYN-RCVD(同步收到)狀態(tài)。
第三次握手:TCP 客戶進(jìn)程收到 B 的確認(rèn)后,還要向 B 給出確認(rèn)。確認(rèn)報(bào)文段的 ACK 置 1,確認(rèn)號 ack = y + 1,而自己的序號 seq = x + 1。這時(shí) ACK 報(bào)文段可以攜帶數(shù)據(jù)。但如果不攜帶數(shù)據(jù)則不消耗序號,這種情況下,下一個(gè)數(shù)據(jù)報(bào)文段的序號仍是 seq = x + 1。這時(shí),TCP 連接已經(jīng)建立,A 進(jìn)入 ESTABLISHED(已建立連接)狀態(tài)。
為了防止已經(jīng)失效的連接請求報(bào)文段突然又傳送到了 B,因而產(chǎn)生錯(cuò)誤。比如下面這種情況:A 發(fā)出的第一個(gè)連接請求報(bào)文段并沒有丟失,而是在網(wǎng)路結(jié)點(diǎn)長時(shí)間滯留了,以致于延誤到連接釋放以后的某個(gè)時(shí)間段才到達(dá) B。本來這是一個(gè)早已失效的報(bào)文段。但是 B 收到此失效的鏈接請求報(bào)文段后,就誤認(rèn)為 A 又發(fā)出一次新的連接請求。于是就向 A 發(fā)出確認(rèn)報(bào)文段,同意建立連接。
對于上面這種情況,如果不進(jìn)行第三次握手,B 發(fā)出確認(rèn)后就認(rèn)為新的運(yùn)輸連接已經(jīng)建立了,并一直等待 A 發(fā)來數(shù)據(jù)。B 的許多資源就這樣白白浪費(fèi)了。
如果采用了三次握手,由于 A 實(shí)際上并沒有發(fā)出建立連接請求,所以不會理睬 B 的確認(rèn),也不會向 B 發(fā)送數(shù)據(jù)。B 由于收不到確認(rèn),就知道 A 并沒有要求建立連接。
有人可能會說 A 發(fā)出第三次握手的信息后在沒有接收到 B 的請求就已經(jīng)進(jìn)入了連接狀態(tài),那如果 A 的這個(gè)確認(rèn)包丟失或者滯留了怎么辦?
我們需要明白一點(diǎn),完全可靠的通信協(xié)議是不存在的。在經(jīng)過三次握手之后,客戶端和服務(wù)端已經(jīng)可以確認(rèn)之前的通信狀況,都收到了確認(rèn)信息。所以即便再增加握手次數(shù)也不能保證后面的通信完全可靠,所以是沒有必要的。
接收端傳回發(fā)送端所發(fā)送的 SYN 是為了告訴發(fā)送端,我接收到的信息確實(shí)就是你所發(fā)送的信號了。
SYN 是 TCP / IP 建立連接時(shí)使用的握手信號。在客戶機(jī)和服務(wù)器之間建立正常的 TCP 網(wǎng)絡(luò)連接時(shí),客戶機(jī)首先發(fā)出一個(gè) SYN 消息,服務(wù)器使用 SYN-ACK 應(yīng)答表示接收到了這個(gè)消息,最后客戶機(jī)再以 ACK(Acknowledgement[漢譯:確認(rèn)字符,在數(shù)據(jù)通信傳輸中,接收站發(fā)給發(fā)送站的一種傳輸控制字符。它表示確認(rèn)發(fā)來的數(shù)據(jù)已經(jīng)接受無誤])消息響應(yīng)。這樣在客戶機(jī)和服務(wù)器之間才能建立起可靠的 TCP 連接,數(shù)據(jù)才可以在客戶機(jī)和服務(wù)器之間傳遞。
雙方通信無誤必須是兩者互相發(fā)送信息都無誤。傳了 SYN,證明發(fā)送方到接收方的通道沒有問題,但是接收方到發(fā)送方的通道還需要 ACK 信號來進(jìn)行驗(yàn)證。
據(jù)傳輸結(jié)束后,通信的雙方都可以釋放連接。現(xiàn)在 A 和 B 都處于 ESTABLISHED 狀態(tài)。
計(jì)算機(jī)網(wǎng)絡(luò)太難?了解這一篇就夠了
第一次揮手:A 的應(yīng)用進(jìn)程先向其 TCP 發(fā)出連接釋放報(bào)文段,并停止再發(fā)送數(shù)據(jù),主動(dòng)關(guān)閉 TCP 連接。A 把連接釋放報(bào)文段首部的終止控制位 FIN 置 1,其序號 seq = u(等于前面已傳送過的數(shù)據(jù)的最后一個(gè)字節(jié)的序號加 1),這時(shí) A 進(jìn)入 FIN-WAIT-1(終止等待1)狀態(tài),等待 B 的確認(rèn)。請注意:TCP 規(guī)定,F(xiàn)IN 報(bào)文段即使不攜帶數(shù)據(jù),也將消耗掉一個(gè)序號。
第二次揮手:B 收到連接釋放報(bào)文段后立即發(fā)出確認(rèn),確認(rèn)號是 ack = u + 1,而這個(gè)報(bào)文段自己的序號是 v(等于 B 前面已經(jīng)傳送過的數(shù)據(jù)的最后一個(gè)字節(jié)的序號加1),然后 B 就進(jìn)入 CLOSE-WAIT(關(guān)閉等待)狀態(tài)。TCP 服務(wù)端進(jìn)程這時(shí)應(yīng)通知高層應(yīng)用進(jìn)程,因而從 A 到 B 這個(gè)方向的連接就釋放了,這時(shí)的 TCP 連接處于半關(guān)閉(half-close)狀態(tài),即 A 已經(jīng)沒有數(shù)據(jù)要發(fā)送了,但 B 若發(fā)送數(shù)據(jù),A 仍要接收。也就是說,從 B 到 A 這個(gè)方向的連接并未關(guān)閉,這個(gè)狀態(tài)可能會持續(xù)一段時(shí)間。A 收到來自 B 的確認(rèn)后,就進(jìn)入 FIN-WAIT-2(終止等待2)狀態(tài),等待 B 發(fā)出的連接釋放報(bào)文段。
第三次揮手:若 B 已經(jīng)沒有要向 A 發(fā)送的數(shù)據(jù),其應(yīng)用進(jìn)程就通知 TCP 釋放連接。這時(shí) B 發(fā)出的連接釋放報(bào)文段必須使 FIN = 1。假定 B 的序號為 w(在半關(guān)閉狀態(tài),B 可能又發(fā)送了一些數(shù)據(jù))。B 還必須重復(fù)上次已發(fā)送過的確認(rèn)號 ack = u + 1。這時(shí) B 就進(jìn)入 LAST-ACK(最后確認(rèn))狀態(tài),等待 A 的確認(rèn)。
第四次揮手:A 在收到 B 的連接釋放報(bào)文后,必須對此發(fā)出確認(rèn)。在確認(rèn)報(bào)文段中把 ACK 置 1,確認(rèn)號 ack = w + 1,而自己的序號 seq = u + 1(前面發(fā)送的 FIN 報(bào)文段要消耗一個(gè)序號)。然后進(jìn)入 TIME-WAIT(時(shí)間等待) 狀態(tài)。請注意,現(xiàn)在 TCP 連接還沒有釋放掉。必須經(jīng)過時(shí)間等待計(jì)時(shí)器設(shè)置的時(shí)間 2MSL(MSL:最長報(bào)文段壽命)后,A 才能進(jìn)入到 CLOSED 狀態(tài),然后撤銷傳輸控制塊,結(jié)束這次 TCP 連接。當(dāng)然如果 B 一收到 A 的確認(rèn)就進(jìn)入 CLOSED 狀態(tài),然后撤銷傳輸控制塊。所以在釋放連接時(shí),B 結(jié)束 TCP 連接的時(shí)間要早于 A。
1. 為了保證 A 發(fā)送的最后一個(gè) ACK 報(bào)文段能夠到達(dá) B。這個(gè) ACK 報(bào)文段有可能丟失,因而使處在 LAST-ACK 狀態(tài)的 B 收不到對已發(fā)送的 FIN + ACK 報(bào)文段的確認(rèn)。B 會超時(shí)重傳這個(gè) FIN+ACK 報(bào)文段,而 A 就能在 2MSL 時(shí)間內(nèi)(超時(shí) + 1MSL 傳輸)收到這個(gè)重傳的 FIN+ACK 報(bào)文段。接著 A 重傳一次確認(rèn),重新啟動(dòng) 2MSL 計(jì)時(shí)器。最后,A 和 B 都正常進(jìn)入到 CLOSED 狀態(tài)。如果 A 在 TIME-WAIT 狀態(tài)不等待一段時(shí)間,而是在發(fā)送完 ACK 報(bào)文段后立即釋放連接,那么就無法收到 B 重傳的 FIN + ACK 報(bào)文段,因而也不會再發(fā)送一次確認(rèn)報(bào)文段,這樣,B 就無法按照正常步驟進(jìn)入 CLOSED 狀態(tài)。
2. 防止已失效的連接請求報(bào)文段出現(xiàn)在本連接中。A 在發(fā)送完最后一個(gè) ACK 報(bào)文段后,再經(jīng)過時(shí)間 2MSL,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失。這樣就可以使下一個(gè)連接中不會出現(xiàn)這種舊的連接請求報(bào)文段。
當(dāng)服務(wù)器執(zhí)行第二次揮手之后, 此時(shí)證明客戶端不會再向服務(wù)端請求任何數(shù)據(jù), 但是服務(wù)端可能還正在給客戶端發(fā)送數(shù)據(jù)(可能是客戶端上一次請求的資源還沒有發(fā)送完畢),所以此時(shí)服務(wù)端會等待把之前未傳輸完的數(shù)據(jù)傳輸完畢之后再發(fā)送關(guān)閉請求。
除時(shí)間等待計(jì)時(shí)器外,TCP 還有一個(gè)?;钣?jì)時(shí)器(keepalive timer)。設(shè)想這樣的場景:客戶已主動(dòng)與服務(wù)器建立了 TCP 連接。但后來客戶端的
主機(jī)突然發(fā)生故障。顯然,服務(wù)器以后就不能再收到客戶端發(fā)來的數(shù)據(jù)。因此,應(yīng)當(dāng)有措施使服務(wù)器不要再白白等待下去。這就需要使用?;钣?jì)時(shí)器了。
服務(wù)器每收到一次客戶的數(shù)據(jù),就重新設(shè)置?;钣?jì)時(shí)器,時(shí)間的設(shè)置通常是兩個(gè)小時(shí)。若兩個(gè)小時(shí)都沒有收到客戶端的數(shù)據(jù),服務(wù)端就發(fā)送一個(gè)探測報(bào)文段,以后則每隔 75 秒鐘發(fā)送一次。若連續(xù)發(fā)送 10個(gè) 探測報(bào)文段后仍然無客戶端的響應(yīng),服務(wù)端就認(rèn)為客戶端出了故障,接著就關(guān)閉這個(gè)連接。
1. 數(shù)據(jù)包校驗(yàn):目的是檢測數(shù)據(jù)在傳輸過程中的任何變化,若校驗(yàn)出包有錯(cuò),則丟棄報(bào)文段并且不給出響應(yīng),這時(shí) TCP 發(fā)送數(shù)據(jù)端超時(shí)后會重發(fā)數(shù)據(jù);
2. 對失序數(shù)據(jù)包重排序:既然 TCP 報(bào)文段作為 IP 數(shù)據(jù)報(bào)來傳輸,而 IP 數(shù)據(jù)報(bào)的到達(dá)可能會失序,因此 TCP 報(bào)文段的到達(dá)也可能會失序。TCP 將對失序數(shù)據(jù)進(jìn)行重新排序,然后才交給應(yīng)用層;
3. 丟棄重復(fù)數(shù)據(jù):對于重復(fù)數(shù)據(jù),能夠丟棄重復(fù)數(shù)據(jù);
4. 應(yīng)答機(jī)制:當(dāng) TCP 收到發(fā)自 TCP 連接另一端的數(shù)據(jù),它將發(fā)送一個(gè)確認(rèn)。這個(gè)確認(rèn)不是立即發(fā)送,通常將推遲幾分之一秒;
5. 超時(shí)重發(fā):當(dāng) TCP 發(fā)出一個(gè)段后,它啟動(dòng)一個(gè)定時(shí)器,等待目的端確認(rèn)收到這個(gè)報(bào)文段。如果不能及時(shí)收到一個(gè)確認(rèn),將重發(fā)這個(gè)報(bào)文段;
6. 流量控制:TCP 連接的每一方都有固定大小的緩沖
空間。TCP 的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù),這可以防止較快
主機(jī)致使較慢
主機(jī)的緩沖區(qū)溢出,這就是流量控制。TCP 使用的流量控制協(xié)議是可變大小的滑動(dòng)窗口協(xié)議。
停止等待協(xié)議是為了實(shí)現(xiàn)可靠傳輸?shù)?,它的基本原理就是每發(fā)完一個(gè)分組就停止發(fā)送,等待對方確認(rèn)。在收到確認(rèn)后再發(fā)下一個(gè)分組;在停止等待協(xié)議中,若接收方收到重復(fù)分組,就丟棄該分組,但同時(shí)還要發(fā)送確認(rèn)。主要包括以下幾種情況:無差錯(cuò)情況、出現(xiàn)差錯(cuò)情況(超時(shí)重傳)、確認(rèn)丟失和確認(rèn)遲到、確認(rèn)丟失和確認(rèn)遲到。
停止等待協(xié)議中超時(shí)重傳是指只要超過一段時(shí)間仍然沒有收到確認(rèn),就重傳前面發(fā)送過的分組(認(rèn)為剛才發(fā)送過的分組丟失了)。因此每發(fā)送完一個(gè)分組需要設(shè)置一個(gè)超時(shí)計(jì)時(shí)器,其重傳時(shí)間應(yīng)比數(shù)據(jù)在分組傳輸?shù)钠骄禃r(shí)間更長一些。這種自動(dòng)重傳方式常稱為自動(dòng)重傳請求 ARQ。
連續(xù) ARQ 協(xié)議可提高信道利用率。發(fā)送方維持一個(gè)發(fā)送窗口,凡位于發(fā)送窗口內(nèi)的分組可以連續(xù)發(fā)送出去,而不需要等待對方確認(rèn)。接收方一般采用累計(jì)確認(rèn),對按序到達(dá)的最后一個(gè)分組發(fā)送確認(rèn),表明到這個(gè)分組為止的所有分組都已經(jīng)正確收到了。
TCP 利用滑動(dòng)窗口實(shí)現(xiàn)流量控制的機(jī)制?;瑒?dòng)窗口(Sliding window)是一種流量控制技術(shù)。早期的網(wǎng)絡(luò)通信中,通信雙方不會考慮網(wǎng)絡(luò)的擁擠情況直接發(fā)送數(shù)據(jù)。由于大家不知道網(wǎng)絡(luò)擁塞狀況,同時(shí)發(fā)送數(shù)據(jù),導(dǎo)致中間節(jié)點(diǎn)阻塞掉包,誰也發(fā)不了數(shù)據(jù),所以就有了滑動(dòng)窗口機(jī)制來解決此問題。
TCP 中采用滑動(dòng)窗口來進(jìn)行傳輸控制,滑動(dòng)窗口的大小意味著接收方還有多大的緩沖區(qū)可以用于接收數(shù)據(jù)。發(fā)送方可以通過滑動(dòng)窗口的大小來確定應(yīng)該發(fā)送多少字節(jié)的數(shù)據(jù)。當(dāng)滑動(dòng)窗口為 0 時(shí),發(fā)送方一般不能再發(fā)送數(shù)據(jù)報(bào),但有兩種情況除外,一種情況是可以發(fā)送緊急數(shù)據(jù),例如,允許用戶終止在遠(yuǎn)端機(jī)上的運(yùn)行進(jìn)程。另一種情況是發(fā)送方可以發(fā)送一個(gè) 1 字節(jié)的數(shù)據(jù)報(bào)來通知接收方重新聲明它希望接收的下一字節(jié)及發(fā)送方的滑動(dòng)窗口大小。
TCP 利用滑動(dòng)窗口實(shí)現(xiàn)流量控制。流量控制是為了控制發(fā)送方發(fā)送速率,保證接收方來得及接收。接收方發(fā)送的確認(rèn)報(bào)文中的窗口字段可以用來控制發(fā)送方窗口大小,從而影響發(fā)送方的發(fā)送速率。將窗口字段設(shè)置為 0,則發(fā)送方不能發(fā)送數(shù)據(jù)。
擁塞控制和流量控制不同,前者是一個(gè)全局性的過程,而后者指點(diǎn)對點(diǎn)通信量的控制。在某段時(shí)間,若對網(wǎng)絡(luò)中某一資源的需求超過了該資源所能提供的可用部分,網(wǎng)絡(luò)的性能就要變壞。這種情況就叫擁塞。
擁塞控制就是為了防止過多的數(shù)據(jù)注入到網(wǎng)絡(luò)中,這樣就可以使網(wǎng)絡(luò)中的路由器或鏈路不致于過載。擁塞控制所要做的都有一個(gè)前提,就是網(wǎng)絡(luò)能夠承受現(xiàn)有的網(wǎng)絡(luò)負(fù)荷。擁塞控制是一個(gè)全局性的過程,涉及到所有的
主機(jī),所有的路由器,以及與降低網(wǎng)絡(luò)傳輸性能有關(guān)的所有因素。相反,流量控制往往是點(diǎn)對點(diǎn)通信量的控制,是個(gè)端到端的問題。流量控制所要做到的就是抑制發(fā)送端發(fā)送數(shù)據(jù)的速率,以便使接收端來得及接收。
為了進(jìn)行擁塞控制,TCP 發(fā)送方要維持一個(gè)擁塞窗口(cwnd) 的狀態(tài)變量。擁塞控制窗口的大小取決于網(wǎng)絡(luò)的擁塞程度,并且動(dòng)態(tài)變化。發(fā)送方讓自己的發(fā)送窗口取為擁塞窗口和接收方的接受窗口中較小的一個(gè)。
TCP 的擁塞控制采用了四種算法,即:慢開始、擁塞避免、快重傳和快恢復(fù)。在網(wǎng)絡(luò)層也可以使路由器采用適當(dāng)?shù)姆纸M丟棄策略(如:主動(dòng)隊(duì)列管理 AQM),以減少網(wǎng)絡(luò)擁塞的發(fā)生。
慢開始算法的思路是當(dāng)
主機(jī)開始發(fā)送數(shù)據(jù)時(shí),如果立即把大量數(shù)據(jù)字節(jié)注入到網(wǎng)絡(luò),那么可能會引起網(wǎng)絡(luò)阻塞,因?yàn)楝F(xiàn)在還不知道網(wǎng)絡(luò)的符合情況。經(jīng)驗(yàn)表明,較好的方法是先探測一下,即由小到大逐漸增大發(fā)送窗口,也就是由小到大逐漸增大擁塞窗口數(shù)值。cwnd 初始值為 1,每經(jīng)過一個(gè)傳播輪次,cwnd 加倍。
擁塞避免算法的思路是讓擁塞窗口 cwnd 緩慢增大,即每經(jīng)過一個(gè)往返時(shí)間 RTT 就把發(fā)送方的 cwnd 加 1。
在 TCP/IP 中,快速重傳和快恢復(fù)(fast retransmit and recovery,F(xiàn)RR)是一種擁塞控制算法,它能快速恢復(fù)丟失的數(shù)據(jù)包。
沒有 FRR,如果數(shù)據(jù)包丟失了,TCP 將會使用定時(shí)器來要求傳輸暫停。在暫停的這段時(shí)間內(nèi),沒有新的或復(fù)制的數(shù)據(jù)包被發(fā)送。有了 FRR,如果接收機(jī)接收到一個(gè)不按順序的數(shù)據(jù)段,它會立即給發(fā)送機(jī)發(fā)送一個(gè)重復(fù)確認(rèn)。如果發(fā)送機(jī)接收到三個(gè)重復(fù)確認(rèn),它會假定確認(rèn)件指出的數(shù)據(jù)段丟失了,并立即重傳這些丟失的數(shù)據(jù)段。
有了 FRR,就不會因?yàn)橹貍鲿r(shí)要求的暫停被耽誤。當(dāng)有單獨(dú)的數(shù)據(jù)包丟失時(shí),快速重傳和快恢復(fù)(FRR)能最有效地工作。當(dāng)有多個(gè)數(shù)據(jù)信息包在某一段很短的時(shí)間內(nèi)丟失時(shí),它則不能很有效地工作。
在進(jìn)行 Java NIO 學(xué)習(xí)時(shí),可能會發(fā)現(xiàn):如果客戶端連續(xù)不斷的向服務(wù)端發(fā)送數(shù)據(jù)包時(shí),服務(wù)端接收的數(shù)據(jù)會出現(xiàn)兩個(gè)數(shù)據(jù)包粘在一起的情況。
1. TCP 是基于字節(jié)流的,雖然應(yīng)用層和 TCP 傳輸層之間的數(shù)據(jù)交互是大小不等的數(shù)據(jù)塊,但是 TCP 把這些數(shù)據(jù)塊僅僅看成一連串無結(jié)構(gòu)的字節(jié)流,沒有邊界;
2. 從 TCP 的幀結(jié)構(gòu)也可以看出,在 TCP 的首部沒有表示數(shù)據(jù)長度的字段。
基于上面兩點(diǎn),在使用 TCP 傳輸數(shù)據(jù)時(shí),才有粘包或者拆包現(xiàn)象發(fā)生的可能。一個(gè)數(shù)據(jù)包中包含了發(fā)送端發(fā)送的兩個(gè)數(shù)據(jù)包的信息,這種現(xiàn)象即為粘包。
接收端收到了兩個(gè)數(shù)據(jù)包,但是這兩個(gè)數(shù)據(jù)包要么是不完整的,要么就是多出來一塊,這種情況即發(fā)生了拆包和粘包。拆包和粘包的問題導(dǎo)致接收端在處理的時(shí)候會非常困難,因?yàn)闊o法區(qū)分一個(gè)完整的數(shù)據(jù)包。
采用 TCP 協(xié)議傳輸數(shù)據(jù)的客戶端與服務(wù)器經(jīng)常是保持一個(gè)長連接的狀態(tài)(一次連接發(fā)一次數(shù)據(jù)不存在粘包),雙方在連接不斷開的情況下,可以一直傳輸數(shù)據(jù)。但當(dāng)發(fā)送的數(shù)據(jù)包過于的小時(shí),那么 TCP 協(xié)議默認(rèn)的會啟用 Nagle 算法,將這些較小的數(shù)據(jù)包進(jìn)行合并發(fā)送(緩沖區(qū)數(shù)據(jù)發(fā)送是一個(gè)堆壓的過程);這個(gè)合并過程就是在發(fā)送緩沖區(qū)中進(jìn)行的,也就是說數(shù)據(jù)發(fā)送出來它已經(jīng)是粘包的狀態(tài)了。
接收方采用 TCP 協(xié)議接收數(shù)據(jù)時(shí)的過程是這樣的:數(shù)據(jù)到接收方,從網(wǎng)絡(luò)模型的下方傳遞至傳輸層,傳輸層的 TCP 協(xié)議處理是將其放置接收緩沖區(qū),然后由應(yīng)用層來主動(dòng)獲?。– 語言用 recv、read 等函數(shù));這時(shí)會出現(xiàn)一個(gè)問題,就是我們在程序中調(diào)用的讀取數(shù)據(jù)函數(shù)不能及時(shí)的把緩沖區(qū)中的數(shù)據(jù)拿出來,而下一個(gè)數(shù)據(jù)又到來并有一部分放入的緩沖區(qū)末尾,等我們讀取數(shù)據(jù)時(shí)就是一個(gè)粘包。(放數(shù)據(jù)的速度 > 應(yīng)用層拿數(shù)據(jù)速度)
分包機(jī)制一般有兩個(gè)通用的解決方法:
1. 特殊字符控制;
2. 在包頭首都添加數(shù)據(jù)包的長度。
如果使用 netty 的話,就有專門的編碼器和解碼器解決拆包和粘包問題了。
tips:UDP 沒有粘包問題,但是有丟包和亂序。不完整的包是不會有的,收到的都是完全正確的包。傳送的數(shù)據(jù)單位協(xié)議是 UDP 報(bào)文或用戶數(shù)據(jù)報(bào),發(fā)送的時(shí)候既不合并,也不拆分。
1. 100 Continue :表明到目前為止都很正常,客戶端可以繼續(xù)發(fā)送請求或者忽略這個(gè)響應(yīng)。
1. 200 OK
2. 204 No Content :請求已經(jīng)成功處理,但是返回的響應(yīng)報(bào)文不包含實(shí)體的主體部分。一般在只需要從客戶端往服務(wù)器發(fā)送信息,而不需要返回?cái)?shù)據(jù)時(shí)使用。
3. 206 Partial Content :表示客戶端進(jìn)行了范圍請求,響應(yīng)報(bào)文包含由 Content-Range 指定范圍的實(shí)體內(nèi)容。
1. 301 Moved Permanently :永久性重定向;
2. 302 Found :臨時(shí)性重定向;
3. 303 See Other :和 302 有著相同的功能,但是 303 明確要求客戶端應(yīng)該采用 GET 方法獲取資源。
4. 304 Not Modified :如果請求報(bào)文首部包含一些條件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不滿足條件,則服務(wù)器會返回 304 狀態(tài)碼。
5. 307 Temporary Redirect :臨時(shí)重定向,與 302 的含義類似,但是 307 要求瀏覽器不會把重定向請求的 POST 方法改成 GET 方法。
1. 400 Bad Request :請求報(bào)文中存在語法錯(cuò)誤。
2. 401 Unauthorized :該狀態(tài)碼表示發(fā)送的請求需要有認(rèn)證信息(BASIC 認(rèn)證、DIGEST 認(rèn)證)。如果之前已進(jìn)行過一次請求,則表示用戶認(rèn)證失敗。
3. 403 Forbidden :請求被拒絕。
4. 404 Not Found
1. 500 Internal Server Error :服務(wù)器正在執(zhí)行請求時(shí)發(fā)生錯(cuò)誤;
2. 503 Service Unavailable :服務(wù)器暫時(shí)處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無法處理請求。
301,302 都是 HTTP 狀態(tài)的編碼,都代表著某個(gè) URL 發(fā)生了轉(zhuǎn)移。
301 redirect: 301 代表永久性轉(zhuǎn)移(Permanently Moved)
302 redirect: 302 代表暫時(shí)性轉(zhuǎn)移(Temporarily Moved)
Forward 和 Redirect 代表了兩種請求轉(zhuǎn)發(fā)方式:直接轉(zhuǎn)發(fā)和間接轉(zhuǎn)發(fā)。
直接轉(zhuǎn)發(fā)方式(Forward):客戶端和瀏覽器只發(fā)出一次請求,Servlet、HTML、JSP 或其它信息資源,由第二個(gè)信息資源響應(yīng)該請求,在請求對象 request 中,保存的對象對于每個(gè)信息資源是共享的。
間接轉(zhuǎn)發(fā)方式(Redirect):實(shí)際是兩次 HTTP 請求,服務(wù)器端在響應(yīng)第一次請求的時(shí)候,讓瀏覽器再向另外一個(gè) URL 發(fā)出請求,從而達(dá)到轉(zhuǎn)發(fā)的目的。
直接轉(zhuǎn)發(fā)就相當(dāng)于:“A 找 B 借錢,B 說沒有,B 去找 C 借,借到借不到都會把消息傳遞給 A”;
間接轉(zhuǎn)發(fā)就相當(dāng)于:"A 找 B 借錢,B 說沒有,讓 A 去找 C 借"。
客戶端發(fā)送的 請求報(bào)文 第一行為請求行,包含了方法字段。
1. GET:獲取資源,當(dāng)前網(wǎng)絡(luò)中絕大部分使用的都是 GET;
2. HEAD:獲取報(bào)文首部,和 GET 方法類似,但是不返回報(bào)文實(shí)體主體部分;
3. POST:傳輸實(shí)體主體
4. PUT:上傳文件,由于自身不帶驗(yàn)證機(jī)制,任何人都可以上傳文件,因此存在安全性問題,一般不使用該方法。
5. PATCH:對資源進(jìn)行部分修改。PUT 也可以用于修改資源,但是只能完全替代原始資源,PATCH 允許部分修改。
6. OPTIONS:查詢指定的 URL 支持的方法;
7. CONNECT:要求在與代理服務(wù)器通信時(shí)建立隧道。使用
ssl(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協(xié)議把通信內(nèi)容加密后經(jīng)網(wǎng)絡(luò)隧道傳輸。
8. TRACE:追蹤路徑。服務(wù)器會將通信路徑返回給客戶端。發(fā)送請求時(shí),在 Max-Forwards 首部字段中填入數(shù)值,每經(jīng)過一個(gè)服務(wù)器就會減 1,當(dāng)數(shù)值為 0 時(shí)就停止傳輸。通常不會使用 TRACE,并且它容易受到 XST 攻擊(Cross-Site Tr
分享標(biāo)題:計(jì)算機(jī)網(wǎng)絡(luò)太難?了解這一篇就夠了
標(biāo)題來源:http://m.rwnh.cn/news35/99035.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、用戶體驗(yàn)、網(wǎng)站排名、企業(yè)網(wǎng)站制作、自適應(yīng)網(wǎng)站、面包屑導(dǎo)航
廣告
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源:
創(chuàng)新互聯(lián)