當被尬聊網(wǎng)絡(luò)協(xié)議、我們可以侃點什么?

正如標題所寫。這篇文章致力于網(wǎng)絡(luò)協(xié)議的初級掃盲、方便應(yīng)對日常甚至面試中的尬聊、也是為了對剛補完的網(wǎng)絡(luò)協(xié)議做個歸納。

目錄

  • TCP/IP協(xié)議族的體系結(jié)構(gòu)
    • 四層協(xié)議模型
    • 每層的作用
    • TCP/IP協(xié)議整體的工作流程
  • 網(wǎng)絡(luò)層
    • 路由器是如何工作的?--路由協(xié)議
      • 路由器
      • 距離向量路由算法
      • 鏈路狀態(tài)路由算法
    • IP地址是個啥?--IP協(xié)議
      • A、B、C、D、E共五類網(wǎng)絡(luò)地址
      • 子網(wǎng)掩碼
      • 分片與重組
      • NAT網(wǎng)絡(luò)地址轉(zhuǎn)換
    • 未來的新型IP地址--IPv6
    • MAC地址有什么作用?--ARP協(xié)議
    • 我們總說ping一下。本質(zhì)是個啥?--ICMP協(xié)議
    • 如何動態(tài)分配IP地址?--廣播與多播
  • 傳輸層
  • 應(yīng)用層
    • HTTP
      • HTTP1.0
      • HTTP1.1
      • HTTP2.0
      • HTTP狀態(tài)碼
      • Cookie
      • Session
    • HTTPS
  • 最后:網(wǎng)絡(luò)協(xié)議到底有沒有用?

TCP/IP協(xié)議族的體系結(jié)構(gòu)

  • 四層協(xié)議模型

雖然與OSI有所不同、但也只是將某些層級合并了而已。

圖1-四層協(xié)議模型

有人說是四層、也有人說是五層(將網(wǎng)絡(luò)接口層分為數(shù)據(jù)鏈路層和物理層)。但是畢竟是個認為定義的東西、沒必要拼個你死我活、理解每一層的作用就好(也有人說ARP以及RARP該歸屬物理鏈路層、一樣沒必要爭論)。

  • 每層的作用

嘗試性的總結(jié)以及類比一下、但是不確保100%吻合、因為現(xiàn)實畢竟和網(wǎng)絡(luò)上不同(你見過誰家快遞員專職住你公司里簽單子?)。

圖2-每層的作用
  1. 四層結(jié)構(gòu)(橙色)全部處于主機內(nèi)部、并且源主機目標主機甚至路由器都含有它們。
  2. 應(yīng)用層并不代指APP、而是供APP調(diào)用(比如HTTP)。
  3. 傳輸層負責這次傳輸?shù)木唧w規(guī)則(重發(fā)、擁塞控制)。
  4. 網(wǎng)絡(luò)層只負責傳輸、其余全部不管。
  5. 物理鏈路層實際上就是網(wǎng)卡(比如以前手機的網(wǎng)卡不能連wifi)。
  • TCP/IP協(xié)議整體的工作流程

原始數(shù)據(jù)包會經(jīng)過一層一層的封裝(為了讓下一層能夠識別必須添加特定的包頭)、向下傳遞。而后在目的地一層一層將數(shù)據(jù)取出。

圖3-TCP/IP協(xié)議整體的工作流程


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

是TCP/IP協(xié)議中最重要的一層

負責報文(數(shù)據(jù)包)的轉(zhuǎn)發(fā)以及路徑的選擇

包括但不限于家用路由器、這里更多的指運營商處的大型路由器。

路由表

路徑選擇主要依靠路由表(也就是通過我可以到達網(wǎng)絡(luò)的表格)實現(xiàn)。包括靜態(tài)路由表(網(wǎng)絡(luò)管理員負責建立、但基本沒人用)以及動態(tài)路由表(通過路由協(xié)議建立)。

工作原理
圖4-路由器工作原理
  1. 如果目的地址存在于路由表中、那么直接轉(zhuǎn)發(fā)。
  2. 如果目的地址不存在于路由表中、那么則發(fā)給默認路由。
  3. 通過網(wǎng)絡(luò)號而不是整個IP地址進行路由判斷
  • 路由協(xié)議

幫助路由器建立路由表

分為兩種算法實現(xiàn):

距離向量路由算法

要求路由器將自己的路由表發(fā)送到臨近的節(jié)點上

鏈路狀態(tài)路由算法

只發(fā)送路由表中描述自身鏈路狀態(tài)的部分到臨近的節(jié)點上

二者比較

鏈路狀態(tài)算法相比距離向量算法在大型網(wǎng)絡(luò)上更有優(yōu)勢。
由于發(fā)送的數(shù)據(jù)更精簡、所以收斂速度更快、網(wǎng)絡(luò)開銷也更小。

路由表到底有多大?

具體要看與自己需要選擇轉(zhuǎn)發(fā)的網(wǎng)絡(luò)有多大。
比如、對于家用路由器的路由表自然只要維護自己內(nèi)部的主機就好、一旦發(fā)現(xiàn)數(shù)據(jù)包不數(shù)據(jù)自己內(nèi)部就直接丟給默認端口(當然大型路由器也一樣)。

具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--路由協(xié)議》

————————

一種無連接的傳輸協(xié)議。只負責數(shù)據(jù)包的傳輸、不對任何問題負責。

其實和UDP很像、但是IP數(shù)據(jù)包的包頭中是不含端口號的、只針對主機(IP地址)之間進行傳輸。

A、B、C、D、E共五類網(wǎng)絡(luò)地址
圖5-五類網(wǎng)絡(luò)地址

常用的網(wǎng)絡(luò)地址為ABC三類:
A類:0開頭、后24位作為主機號、其余作為網(wǎng)絡(luò)號。
B類:10開頭、后16位作為主機號、其余作為網(wǎng)絡(luò)號。
C類:110開頭、后8位作為主機號、其余作為網(wǎng)絡(luò)號(最常用)
D類:用于UDP多播。

子網(wǎng)掩碼

對地址結(jié)構(gòu)的擴展、用于確定網(wǎng)絡(luò)號與主機號的結(jié)構(gòu)

比如有兩個C類地址、他們本屬不同的網(wǎng)絡(luò)。但如果合理使用子網(wǎng)技術(shù)、就可以把他們的網(wǎng)絡(luò)號合并從而形成一個子網(wǎng)。


圖6-子網(wǎng)掩碼

分片與重組

實際使用中經(jīng)常會遇到一個IP包傳輸不完(比如途中某個物理網(wǎng)絡(luò)最大傳輸長度限制)、需要拆分的情況。

對于大于MTU(最大傳輸長度)的數(shù)據(jù)包、會被拆分然后傳輸、最后在目的地重組恢復。
分片動作通常由路由器完成、重組由目標主機完成(降低了中間路由器壓力)。

需要注意的是一旦任何分片丟失、目的主機都會要求重傳所有分片

NAT網(wǎng)絡(luò)地址轉(zhuǎn)換

一種通過將內(nèi)部不同私網(wǎng)IP及端口公網(wǎng)端口綁定、以達到內(nèi)部所有計算機通過一個公網(wǎng)IP進行外界溝通的作用。

我們現(xiàn)在基本都是使用了這個技術(shù)、如果你有兩臺主機就會發(fā)現(xiàn)他們的公網(wǎng)IP其實是相同的。
這個技術(shù)在很大程度上也緩解了IP地址不足的問題(雖然不能根治)。

具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--IP協(xié)議》

————————

  • 未來的新型IP地址--IPv6

  1. 擴展地址
    有IPv4的32(46億個)位擴展為128位(340萬億個)
  2. 簡化的包頭
  3. 流標記
    相同流向的數(shù)據(jù)包不需要每次進行尋路
具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--IPv6》

————————

用IP地址映射所對應(yīng)的MAC地址

在物理層上、并不是通過IP地址來確定通訊目標(有可能是因為網(wǎng)絡(luò)興起初期協(xié)議很多、IP協(xié)議并不占主導)、而是通過網(wǎng)卡的MAC地址。
IP地址指向最終的主機地址、而MAC地址指向下一跳的目標位置。

工作流程

①當電腦沒有網(wǎng)關(guān)(采用代理ARP)時:"跨網(wǎng)段訪問誰,就問誰的MAC"

②當電腦有網(wǎng)關(guān)(采用正常ARP)時:"跨網(wǎng)段訪問誰,都問網(wǎng)關(guān)的MAC"

③無論哪種ARP,跨網(wǎng)段通信時,發(fā)送方請求得到的目標MAC地址都是網(wǎng)關(guān)MAC。

與之對應(yīng)的還有RARP協(xié)議(用于網(wǎng)絡(luò)中某些需要遠程啟動的無盤工作站獲取IP地址

具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--ARP協(xié)議和RARP協(xié)議》

————————

發(fā)現(xiàn)錯誤的路由器、向數(shù)據(jù)包的(通過IP數(shù)據(jù)包的信息獲取)源主機地址發(fā)送一個ICMP數(shù)據(jù)包、并且通過ICMP數(shù)據(jù)包報告出錯的原因。

  1. ICMP協(xié)議是IP協(xié)議的補充、ICMP與IP協(xié)議位于同一個層次(IP層),但ICMP報文是封裝在IP數(shù)據(jù)包的數(shù)據(jù)部分進行傳輸?shù)摹?/p>

  2. 總的來看可以分為如圖所示的三大 類:差錯報告、控制報文和請求應(yīng)答報文

    圖6-ICMP報文種類

大部分都是給源路由器看的(比如網(wǎng)絡(luò)不可達/源抑制等等)

我們?nèi)粘S玫降?code>ping命令:作用就是我們發(fā)送請求報文、目標服務(wù)器返回一個應(yīng)答報文以此判斷目標主機是否存在。

具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--ICMP協(xié)議》

————————

如何動態(tài)分配IP地址?--廣播與多播

動態(tài)主機配置協(xié)議(Dynamic Host Configuration Protocol,DHCP),在認定本地子網(wǎng)上有一個DHCP服務(wù)器主機或中繼主機的前提下,DHCP客戶主機向廣播地址(通常是255.255.255.255,因為客戶主機還不知道自己的IP地址、子網(wǎng)掩碼及本子網(wǎng)的受限廣播地址)發(fā)送自己的請求。

  1. 單播
    點對點的通訊方式

  2. 廣播(IPv4)
    向所有的主機同時通訊

  3. 多播(組播)
    向某些主機同時通訊

  4. 泛播(IPv6)
    向任意一些主機中的某一個發(fā)起通訊。可以參照負載均衡來理解、我想知道當前時間、10個服務(wù)器有資格響應(yīng)、但最終只有一個離我最近的服務(wù)器完成響應(yīng)。

注意這里雖然在網(wǎng)絡(luò)層所提到的廣播多播、也就是通過特定的IP地址實現(xiàn)。例如:
主機位全部為1(xxx.xxx.xxx.255)則為該網(wǎng)絡(luò)的廣播地址。

但并不妨礙我們在UDP中使用
比如我們可以監(jiān)聽一個端口、然后向本地廣播地址發(fā)送UDP數(shù)據(jù)包進行本地群組聊天或者通過單播地址點對點聊天

TCP不支持廣播和多播:具體等說到TCP時再說。

具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--廣播與多播》

傳輸層

在運行在不同主機上的進程提供邏輯通訊的功能、使彼此感覺直接相連

  • 套接字(socket)

總是成對出現(xiàn)、是應(yīng)用層到傳輸層的門戶。

套接字本質(zhì)上就是操作系統(tǒng)為傳輸層公開的API、幫助我們組裝傳輸層數(shù)據(jù)包并交給IP層發(fā)送。

套接字(socket)并不單指TCP(長連接)、TCP/IP協(xié)議族中包括三種套接字:

  1. 流式套接字--TCP協(xié)議專屬
  2. 數(shù)據(jù)報套接字--UDP協(xié)議專屬
  3. 原始套接字--可以直接訪問IP層

我們可以舉個C語言socket編程的例子:

//創(chuàng)建一個TCP的scoket
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//創(chuàng)建一個UDP的scoket
SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

——————

  • UDP協(xié)議--(用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol))

不可靠的無連接的數(shù)據(jù)包傳輸服務(wù)

只負責發(fā)送、不保證安全性(確認到達)以及順序。這點其實和IP協(xié)議的本質(zhì)一樣。

所以、UDP可以在不建立連接的情況下隨意向主機的某個端口發(fā)送數(shù)據(jù)(但源主機并不知道是否發(fā)送成功、甚至目標主機都不知道是誰發(fā)來的數(shù)據(jù))。

  • TCP協(xié)議--(傳輸控制協(xié)議Transmission Control Protocol))

面向鏈接的可靠的字節(jié)流傳輸服務(wù)

即TCP協(xié)議數(shù)據(jù)包會保證重發(fā)、有序還有擁塞控制。確保從發(fā)送方發(fā)出的數(shù)據(jù)、按照順序完整的交付給接收方。

所以、TCP鏈接需要經(jīng)歷三次握手(雙方確認相互可以收發(fā)數(shù)據(jù))、四次揮手(雙方先后申請斷開單向鏈接并被確認)

此外TCP是全雙工的、數(shù)據(jù)的發(fā)送、接收可以同時雙向進行。

————————

  • TCP協(xié)議與UDP協(xié)議的比較

借用《《知乎》》上的一個很有趣的例子:

亞當和夏娃分別生活在兩個山頭,山頭之間是萬丈深淵,亞當采集野果需要分享給夏娃,如果他們之間有一條索道(物理連接),野果可以順著索道滑到夏娃那一邊,那就沒有網(wǎng)絡(luò)協(xié)議什么事了。
事實上山頭之間沒有索道。但是亞當何等聰明,于是他想出了一個方法,假設(shè)亞當需要給夏娃10個野果,否則她會餓死。
============================
《《《《《《對于TCP》》》》》》
============================
連接建立
亞當對著夏娃大喊:愛妃,你聽得到嗎?
夏娃回應(yīng):孩他爹,我聽得到!
亞當接著喊:那好,我扔果子給你吃,你接到果子就喊一聲,一共十個。
運送貨物
于是亞當開始扔第一個,夏娃喊收到了一個。
亞當扔第二個,夏娃喊收到兩個。
超時重傳 ( timeout retransmit)
亞當扔第三個,可是夏娃遲遲沒有回音,亞當意識到可能果子落到懸崖了,于是重新扔,夏娃喊收到第三個。
Advertised window size = 0
于是亞當連續(xù)扔了第四、五、六個,夏娃急了:孩他爹,慢點扔,臣妾忙不過來了…
Advertised window size > 0
于是亞當坐下休息,愛妃又開始叫了:繼續(xù)扔吧。
亞當開始扔第七個,夏娃喊收到七個。

關(guān)閉連接
終于亞當扔完了,亞當喊:愛妃,果子扔完了,寡人去忙別的了。
夏娃回復:好的,我也休息一下,再見。
亞當:再見
以上的過程類似TCP連接的過程,TCP是一個虛擬連接
============================
《《《《《《對于UDP》》》》》》
============================
亞當和夏娃吵架了,任憑亞當如何大聲喊,夏娃躲在樹林后生悶氣,一聲不響,亞當害怕夏娃餓死,于是
開始自說自話朝著夏娃的山頭扔玉米棒子:
一個、兩個、三個…
一共扔了十個,但最終扔到對方山頭到底有幾個,亞當沒有底,也許有的玉米棒子落到懸崖了,但是這個效率高啊,可以連續(xù)扔,以前扔10個果子需要一分鐘,現(xiàn)在只需要20秒。
亞當扔果子、扔玉米都有可能扔到懸崖下,但是扔果子為何可以確保對方收到十個?那是因為夏娃收到一個果子,然后喊收到了,如果沒有收到,亞當就重新扔,直到夏娃說收到了。而扔玉米棒子對方?jīng)]有確認,所以對于丟棄的情況無法知道,也無法重新扔。

面向連接的傳輸服務(wù)
  • TCP以連接作為協(xié)議數(shù)據(jù)的最終目標
    TCP協(xié)議的端口是可以復用

對于TCP協(xié)議,要成功建立一個新的鏈接,需要保證新鏈接四個要素組合體的唯一性:客戶端的IP、客戶端的port、服務(wù)器端的IP、服務(wù)器端的port。也就是說,服務(wù)器端的同一個IP和port,可以和同一個客戶端的多個不同端口成功建立多個TCP鏈接(與多個不同的客戶端當然也可以),只要保證【Server IP + Server Port + Client IP + Client Port】這個組合唯一不重復即可。

  • UDP以端口作為協(xié)議數(shù)據(jù)的最終目標
    UDP協(xié)議的端口不可復用

對于UDP協(xié)議、是以監(jiān)聽端口作為操作的。而且在協(xié)議中、源端口和源IP地址都是可選項。哪怕不填(只制定了目的端口和目的地址)也可以成功發(fā)送。

  • TCP協(xié)議需要先建立連接、然后才能發(fā)送/接收數(shù)據(jù)
    并且需要對很多細節(jié)進行協(xié)商(最大數(shù)據(jù)長度、窗口大小、初始序列號等)
  • UDP協(xié)議直接發(fā)送/接收數(shù)據(jù)

可靠的傳輸服務(wù)

  • TCP協(xié)議提供的是可靠的傳輸服務(wù)
    以序列號保證有序、以重發(fā)機制保證成功發(fā)送。
  • UDP協(xié)議提供的是不可靠的傳輸服務(wù)
    可能會丟失、失序、重復等。

面向字節(jié)流的傳輸服務(wù)

  • TCP協(xié)議是以字節(jié)為單位流式傳輸數(shù)據(jù)
    TCP的傳輸是無邊界的
  • UDP協(xié)議是以數(shù)據(jù)塊傳輸數(shù)據(jù)
    UDP的傳輸是有邊界的

——————————

  • TCP應(yīng)用于UDP應(yīng)用

1. TCP
以可靠傳輸為基準:FTP、Telnet、http、自建通道。

2. UDP
對時效性為基準:實時應(yīng)用、多播式應(yīng)用。

使用UDP時應(yīng)該注意一下幾點:
1. 應(yīng)用程序必須自己來保證可靠性
應(yīng)用程序必須有自己的重發(fā)機制、數(shù)據(jù)失序處理、流量控制等。
2. 應(yīng)用程序必須自己來處理大塊數(shù)據(jù)
發(fā)送方對大塊數(shù)據(jù)進行分割、接收方還要進行重組

QQ就是采用《可靠的UDP》+TCP來實現(xiàn)。其中UDP主要負責通訊、TCP負責最低限度狀態(tài)的維持。

影響TCP和UDP選擇的最大原因

很多游戲選擇UDP而非TCP、并不是因為來回的確認包會浪費資源或者拖慢網(wǎng)速(因為可靠的UDP也需要確認包)、更不是三次握手。
更重要的原因是TCP的阻塞窗口機制會《在發(fā)生阻塞時自動減少數(shù)據(jù)段的發(fā)送》、一旦網(wǎng)絡(luò)發(fā)生波動、TCP的這個自宮機制會讓應(yīng)用程序的延遲更高。而在網(wǎng)絡(luò)恢復后、TCP的慢啟動機制也會延緩恢復的時間。

關(guān)于TCP和UDP具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--TCP協(xié)議》《網(wǎng)絡(luò)協(xié)議補完計劃--UDP協(xié)議》

應(yīng)用層

  • HTTP

HTTP連接最顯著的特點是客戶端發(fā)送的每次請求都需要服務(wù)器回送響應(yīng)、在請求結(jié)束后(HTTP1.0)恰當?shù)臅r候(keep-alive)、會主動釋放連接。從建立連接到關(guān)閉連接的過程稱為“一次連接”。

實際上HTTP就是對于TCP的二次封裝、使得我們只需要傳入很少的參數(shù)便能使用TCP鏈接以《請求--應(yīng)答》的方式進行通訊。默認端口為80.

HTTP1.0:
  1. 無連接
    每次通訊結(jié)束會自動釋放鏈接
  2. 無狀態(tài)
    服務(wù)器無法記錄用戶以前的動作
HTTP1.1:
  1. 新頭部字段
    主機名、身份認證、狀態(tài)管理和Cache緩存等
  2. Connection-Keep-Alive
    保持長連接(默認開啟--但是服務(wù)器通常會偷偷的釋放掉連接以節(jié)省資源)
  3. 支持在一次連接中同時發(fā)出多個請求
    但服務(wù)器端必須按照接收到客戶端請求的先后順序依次回送響應(yīng)結(jié)果,以保證客戶端能夠區(qū)分出每次請求的響應(yīng)內(nèi)容。這也叫做《隊首阻塞》。
  4. 斷點續(xù)傳
HTTP2.0:
  1. 多路復用
    基于二進制分幀層,HTTP 2.0可以在共享TCP連接的基礎(chǔ)上,同時發(fā)送請求和響應(yīng)。HTTP消息被分解為獨立的幀,而不破壞消息本身的語義,交錯發(fā)送出去,最后在另一端根據(jù)流ID和首部將它們重新組合起來

  2. 頭部壓縮
    更小的頭部體積、傳輸更快

HTTP狀態(tài)碼

1xx(臨時響應(yīng))、2xx(請求成功)、3xx(重定向)、4xx(客戶機錯誤)、5xx(服務(wù)器錯誤)。

Cookie

服務(wù)器通過響應(yīng)頭發(fā)送一個用于識別身份的cookie字符串《客戶端保存》、客戶端在之后的請求中將該cookie放在請求頭中發(fā)送。

需要注意的是cookie是不能跨域的、而且https和http共用同一個。

Session

與cookie客戶端保存不同、session是由《服務(wù)器生成并保存》每個連接者的身份信息(session)。而這個身份信息與客戶端的cookie綁定、所以也有人說session是基于cookie實現(xiàn)的。

具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--HTTP協(xié)議》

——————————

HTTPS

負責《幫助服務(wù)器和客戶端在安全的環(huán)境下協(xié)商出一個秘鑰》以《進行加密傳輸》。

主要用到了三種技術(shù):

  1. 使用數(shù)字證書以及數(shù)字簽名技術(shù)實現(xiàn)服務(wù)器公鑰認證
  2. 使用公鑰實現(xiàn)在非對稱加密狀態(tài)下協(xié)商通信秘鑰
  3. 使用通信秘鑰實現(xiàn)對稱加密狀態(tài)下的安全通信
具體可以參閱《網(wǎng)絡(luò)協(xié)議補完計劃--HTTPS》

最后:網(wǎng)絡(luò)協(xié)議到底有沒有用?

這個問題沒有定論。因為對于絕大部分人而言、我們只需要了解HTTP、甚至連了解都不用只需要會調(diào)用API就夠了。
所以具體有沒有用、要看工作中有沒有遇到什么問題。

當項目足夠大、或許就用得上了。

以美團移動網(wǎng)絡(luò)的架構(gòu)作為例舉

這個架構(gòu)圖基本上已經(jīng)涵蓋了目前所有的通訊方式、并加以合理利用

TCP子通道:
專用的TCP長連接通道。所有客戶端的HTTP請求默認都會被加工成二進制數(shù)據(jù)包放在專用的TCP通道發(fā)送給代理服務(wù)器。
UDP子通道:
作為TCP的降級方案使用、如果TCP不同則嘗試使用UDP通道通訊。
HTTP子通道:
當TCP與UDP均不可用、則直接使用HTTP對業(yè)務(wù)服務(wù)器進行公網(wǎng)請求。
HTTP通道:
上傳和下載大數(shù)據(jù)包的請求如果放在長連上進行都有可能導致長連通道的擁堵,因此我們將CDN訪問、文件上傳和頻繁的日志上報等放在公網(wǎng)利用HTTP短連進行請求,同時也減輕代理長連服務(wù)器的負擔。
WNS通道:
出于災(zāi)備用TCP通道

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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