![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
爲何有了MAC 層還要走IP 層呢?編程
- mac 地址就好像我的的身份證號,可是和人所在的位置沒有關係
- 因此要實現機器之間的通訊,還須要有ip 地址的概念,ip 地址表達的是當前機器在網絡中的位置,相似於城市名+道路號+門牌號的概念。
什麼是協議瀏覽器
- 協議至關於兩個須要經過網絡通訊的程序達成的一種約定,它規定了報文的交換方式和包含的意義。
- 好比(HTTP)爲了解決在服務器之間傳遞超文本對象的問題,這些超文本對象在服務器中建立和存儲,並由Web 瀏覽器進行可視化,完成用戶對遠程內容的感知和體驗。
什麼是IP 協議緩存
- T C P 和U D P 是兩種最爲著名的傳輸層協議,他們都是使用I P 做爲網絡層協議。
- IP 協議提供了一組數據報文服務,每組分組報文都是由網絡獨立處理和分發
- 就像寄送快遞包裹同樣,爲了實現這個功能,每一個IP 報文必須包含一個目的地址的字段;
- IP 協議只是一個「盡力而爲」的協議,在網絡傳輸過程當中,可能會發生報文丟失、報文順序打亂,重複發送的狀況。
TCP/IP服務器
- TCP 協議可以檢測和恢復IP 層提供的主機到主機的通訊中可能發生的報文丟失、重複及其餘錯誤。
- TCP 提供了一個可信賴的字節流通道,這樣應用程序就不須要考慮這些問題。
- TCP 協議是一種面向鏈接的協議,
- 在使用TCP進行通訊以前,兩個應用程序之間須要創建一個TCP 鏈接,而這個鏈接又涉及到兩臺電腦須要完成握手消息的交換。
UDP/IP網絡
- UDP 協議不會對IP 層產生的錯誤進行修復,
- 而是簡單的擴展了IP 協議「盡力而爲」的數據報文服務
- 使用UDP協議必需要考慮到報文丟失,順序混亂的問題
TCP 是如何作到可靠傳輸的?socket
- 創建可靠的連接
- 因爲TCP 協議是一種可信的傳輸協議,
- 因此在傳輸以前,須要經過三次握手創建一個鏈接,所謂的三次握手,
- 就是在創建TCP 連接時,須要客戶端和服務端總共發送3個包來確認鏈接的創建
![](http://static.javashuo.com/static/loading.gif)
TCP 四次揮手協議性能
- 四次揮手錶示TCP 斷開鏈接的時候,須要客戶端和服務端總共發送4 個包以確認鏈接的斷開
- 客戶端或服務器都可主動發起揮手動做(由於TCP 是一個全雙工協議),
- 在socket 編程中,任何一方執行 close() 操做便可產生揮手操做。
tips:爲何鏈接的時候是三次握手,關閉的時候倒是四次握手?優化
- 三次握手是由於由於當Server 端收到Client 端的SYN 鏈接請求報文後,能夠直接發送SYN+ACK 報文。
- 其中ACK報文是用來應答的,SYN 報文是用來同步的。
- 可是關閉鏈接時,當Server 端收到FIN 報文時,極可能並不會當即關閉SOCKET(由於可能還有消息沒處理完),因此只能先回復一個ACK 報文,告訴Client 端,"你發的FIN 報文我收到了"。
- 只有等到我Server 端全部的報文都發送完了,我才能發送FIN 報文,所以不能一塊兒發送。故須要四步握手。
數據傳輸過程的流量控制和確認機制線程
- 在通訊過程當中,最重要的是數據包,也就是協議傳輸的數據。
- 若是數據的傳送與接收過程中出現收方來不及接收的狀況,這時就須要對發方進行控制以避免數據丟失。
- 利用滑動窗口機制能夠很方便的在TCP 鏈接上實現對發送方的流量控制。
- TCP 的窗口單位是字節,不是報文段,發送方的發送窗口不能超過接收方給出的接收窗口的數值。
滑動窗口協議3d
- 滑動窗口(Sliding window)是一種流量控制技術。
- 因爲你們不知道網絡擁塞情況,同時發送數據,致使中間節點阻塞掉包,誰也發不了數據,
- 因此就有了滑動窗口機制來解決此問題;
滑動窗口圖解:
- 發送和接受方都會維護一個數據幀的序列,這個序列被稱做窗口
- 發送方的窗口大小由接受方肯定,目的在於控制發送速度,以避免接受方的緩存不夠大,而致使溢出,同時控制流量也能夠避免網絡擁塞。
- 圖中的4,5,6 號數據幀已經被髮送出去,可是未收到關聯的ACK,7,8,9 幀則是等待發送。
- 能夠看出發送端的窗口大小爲6,這是由接受端告知的。
- 此時若是發送端收到4 號ACK,則窗口的左邊緣向右收縮,窗口的右邊緣則向右擴展,此時窗口就向前「滑動了」,即數據幀10 也能夠被髮
送。
![](http://static.javashuo.com/static/loading.gif)
發送窗口
- 發送端容許連續發送的幀的序號表。
- 發送端能夠不等待應答而連續發送的最大幀數稱爲發送窗口的尺寸。
接收窗口
- 接收方容許接收的幀的序號表,凡落在 接收窗口內的幀,接收方都必須處理,落在接收窗口外的幀被丟棄。
- 接收方每次容許接收的幀數稱爲接收窗口的尺寸。
正常的通訊過程以下(BIO)
- 這種類型的服務器稱爲「迭代服務器」。
- 迭代服務器是按照順序處理客戶端請求,
- 也就是服務端必需要處理完前一個請求才能對下一個客戶端的請求進行響應。
- 能夠引入線程池對其優化
![](http://static.javashuo.com/static/loading.gif)
TCP 協議的通訊過程
- 對於TCP 通訊來講,每一個TCP Socket 的內核中都有一個發送緩衝區和一個接收緩衝區,
- TCP 的全雙工的工做模式及TCP 的滑動窗口就是依賴於這兩個獨立的Buffer 和該Buffer 的填充狀態。
- 接收緩衝區把數據緩存到內核,若應用進程一直沒有調用Socket 的read 方法進行讀取,那麼該數據會一直被緩存在接收緩衝區內。
- 無論進程是否讀取Socket,對端發來的數據都會通過內核接收並緩存到Socket 的內核接收緩衝區。
- read 所要作的工做,就是把內核接收緩衝區中的數據複製到應用層用戶的Buffer 裏。
- 進程調用Socket 的send 發送數據的時候
- 通常狀況下是將數據從應用層用戶的Buffer 裏複製到Socket 的內核發送緩衝區,而後send 就會在上層返回。
- 換句話說,send 返回時,數據不必定會被髮送到對端。
![](http://static.javashuo.com/static/loading.gif)
- Socket 的接收緩衝區被TCP 用來緩存網絡上收到的數據,一直保存到應用進程讀走爲止。
若是應用進程一直沒有讀取,那麼Buffer 滿了之後,出現的狀況是:
- 通知對端TCP協議中的窗口關閉,保證TCP 接收緩衝區不會移除,保證了TCP 是可靠傳輸的。
- 若是對方無視窗口大小發出了超過窗口大小的數據,那麼接收方會把這些數據丟棄。
如何使用非阻塞提升性能?(NIO)
- 非阻塞要解決的就是I/O 線程與Socket 解耦的問題;
- 所以,它引入了事件機制來達到解耦的目的。
- 咱們能夠認爲NIO 底層中存在一個I/O 調度線程,它不斷的掃描每一個Socket 的緩衝區,當發現寫入緩衝區爲空的時候,它會產生一個Socket 可寫事件,此時程序就能夠把數據寫入到Socket 中。
- 若是一次寫不完,就等待下一次的可寫事件通知;
- 反之,當發現緩衝區裏有數據的時候,它會產生一個Socket 可讀事件,程序收到這個通知事件就能夠從Socket 讀取數據了。
關於NIO
- 傳統的BIO 模型,一個請求一個線程的方式,若是要涉及到上千個客戶端訪問時,會產生不少的問題
- 因此咱們須要一種方法來輪詢一組客戶端,來查找哪一個鏈接須要提供服務,這個就是咱們講的「NIO」;
緩衝區
- 在NIO 中,全部數據都是用緩衝區處理,
- 在讀取數據的時候,它是直接讀到緩衝區中,在寫入數據的時候,也是寫到緩衝區。
- 任什麼時候候訪問NIO 中的數據,都是經過緩衝區進行的操做
通道(Channel )
- Channel 通道,就像一個自來水管同樣,能夠經過它讀取和寫入數據,
- Channel 是全雙工的,因此數據是雙向流動。
多路複用
- 多路複用器Selector,是NIO 的基礎,多路複用器提供選擇已經就緒的任務的能力,
- 簡單來講,Selector 會不斷輪詢註冊上的Channel,
- 若是某個Channel 上面有新的TCP鏈接發生接入、讀、寫事件,這個Channel 就處於就緒狀態,會被Selector 輪詢出來,
- 而後經過SelectionKey 能夠獲取就緒的Channel 進行I/O 操做;
- 一個多路複用器能夠同時輪詢多個Channel。
- 經過這個機制能夠接入成千上萬的客戶端。
![](http://static.javashuo.com/static/loading.gif)
組播協議Multicast
- 有兩種分發類型,廣播(broadcast)和多播(multicast);
- 解決方案是,咱們能夠把複製數據包的工做交給網絡來作,而不是由發送者負責。
- 廣播:網絡中的全部主機都會接收到一份數據副本
- 廣播是主機向子網內全部主機發送消息,子網內全部主機都能收到來自某臺主機的廣播信息,屬於點對全部點的通訊。
- 廣播意味着絡向子網每個主機都投遞一份數據包,不論這些主機是否樂意接收該數據包;
![](http://static.javashuo.com/static/loading.gif)
- 多播:消息只發送給一個多播地址,
- 網絡只是將數據分發給哪些想要接收發送到該多播地址的數據的主機。
- 總的來講,要實現這個功能,只有UDP 是最合適的
- 多播是主機向一組主機發送信息,存在於某個組的全部主機均可以接收到消息,屬於點對多點的通訊。