Java基礎系列:計算機網絡基礎概念

俗世遊子:專一技術研究的程序猿html

網絡

大部分狀況下,作開發的程序猿是是不須要和網絡打交道的,就好比本人:工做這麼多年,去年年初作過一次系統架構,作負載均衡的時候順帶了解了一下這方面的基礎知識,其餘時候根本用不到。java

咱們如今就來簡單聊一聊,簡單到什麼程度:面試

  • 開發涉及到網絡IO方面的問題能知道該怎麼解決,
  • 面試能說個七七八八就夠了

基本知識

首先咱們先要明白什麼是網絡算法

不負責任的說,網絡網絡是由若干節點和鏈接這些節點的鏈路構成,而這些物理鏈路將多臺計算機鏈接在一塊兒,組成了咱們如今的互聯網瀏覽器

促進網絡產生的先決條件:緩存

  • 芯片技術

要知道,世界上第一臺計算機有一個教室那麼大,直到集成電路的產生,將電路作到一塊完整的半導體硅板上,計算機的體積才降低下來安全

  • 網絡理論自己

第二個條件就是網絡理論自己,咱們如今知道,網絡自己分爲不少節點,各個節點之間相互關聯,咱們從起點A發送數據到終點B,發送的數據在網絡中會拆分紅小包,因爲光電傳輸是很是快的,因此在數據包在網絡中傳輸的時候會經過不一樣的路線到達終點B,而後在終點B中進行合併服務器

在這個理論中,兩我的的貢獻很是大:微信

  1. Paul Baran 提出的分佈式可適應信息塊交換集成電路
  2. Donald Davies 提出的封包交換

二者說的是一個問題,就是封包交換算法,解決數據如何從一個點經過複雜網絡到達另外一個點的問題網絡

  • 材料的發展

在1858年的跨大西洋同軸電纜,每分鐘傳輸120個字,而咱們如今採用的雙絞線電纜,經過導線兩兩纏繞,抵消掉信號的干擾,而不一樣材料傳輸速度也不一樣。目前咱們市面上的傳輸速度已經能到達到100Mbps,還有比這個更快的,可以快10倍

光纖採用的是光傳輸,能量在用光傳輸的時候損耗較低,因此速度最快,可以達到10Gbps

  • 軟件應用行業的發展

應用的不斷髮展也形成了網絡的發展,包括如今的5G,衛星上網

網絡模型

隨着網絡的出現,再加上當時商業力量的介入,網絡獲得的大力的發展,出現了OSI網絡模型,即開放式系統互聯模型,它是國際標準組織的一次偉大嘗試,也是世界上第一個試圖在世界範圍內規範網絡標準的框架

七層模型

模型從上向下分別爲:

  • 應用層

也就是咱們日常使用的客戶端,好比微信發送消息,瀏覽器請求地址等等,這裏只負責將請求數據發送出去

  • 表示層

負責協商用於傳輸的數據格式,並轉換數據格式。好比如今說的HTTP協議,數據量太大的話,數據壓縮在這一層,HTTPS數據加密也在這一層完成

  • 會話層

負責管理兩個聯網實體間的網絡,好比客戶端和服務器端產生的鏈接,這條鏈接維持客戶端和服務器端的通訊,而後等到鏈接斷開的時候釋放連接

  • 傳輸層

從傳輸層開始,將負責數據的拆成一個個小包,而後將小包進行封包,並將數據從一個實體(服務器或者應用)發送到另外一個實體,可是並不負責數據的傳輸方式

同時在傳輸層還有如下功能:

  1. 當數據在傳輸過程當中出現問題後採起方式進行糾正,重發或者其餘方式
  2. 控制傳輸數據的速率
  3. 端口尋址,標明參與傳輸的實體的端口號
  • 網絡層

負責把封包從一個IP地址傳輸到另外一個IP地址,這裏的核心就是路由算法。須要經過路由算法獲得下一個節點的地址

  • 數據鏈路層

在這一層確保兩個臨近設備間數據的傳輸,並隱藏底層實現,同時還須要協調傳輸時速率問題

  • 物理層

真正須要發送數據的實際手段,好比:網線,光纖等等的物理方式

看下面的圖,用實際例子來理解一下:
網絡傳輸過程

須要注意的是,OSI模型是沒有實際可行的方案

TCPIP協議

實際上,OSI模型仍是存在一些問題好比說:

咱們在命令行經過ping來測試一個網絡,根據咱們對7層網絡模型的認識,這種程序對於會話層和表示層並非必須的,

並且因爲OSI模型在當時並無實際可行的方案,因此羅伯特.卡恩文頓.頓瑟夫提出了TCP協議,對比OSI模型只有5層,並且在1975年作了成功的實驗,因此從這一點上TCP協議OSI模型更容易讓你們接受

它只有5層:

  • 應用層

這裏不變,也是將數據發送出去的過程

  • 傳輸控制層

解決主機到主機之間的傳輸,在這裏經常使用的也就是咱們耳熟能詳的TCP協議UDP協議

  • 網絡層

在這一層提供了路由和尋址,經過路由斷定和下一跳機制獲得下一個要發送出去的節點

  • 數據鏈路層

兩個節點之間的物理鏈接,在這裏對數據再次封包發送,經常使用的就是ARP協議

  • 物理層

物理層和OSI模型不變

深刻理解

下面咱們來聊一聊在各個層面上咱們常用的協議

應用層協議:HTTP協議

基本概念

HTTP協議,也叫超文本傳輸協議,是處理客戶端和服務器端之間通訊的一種協議,在HTTP協議中的的請求頭和返回體都包含相同的數據格式:

  • Request
GET / HTTP/1.1
Host: http://www.baidu.com
...

<消息請求body>
  • Response
GET HTTP/1.1 200 ok
...

<返回體>

在Request和Response中包含不少的屬性

只要咱們可以按照HTTP指定的協議返回,那麼咱們也能夠本身實現一個Http服務器,好比:

public class RawHttpSocket {

    private ServerSocket serverSocket;
    Function<String, String> handler;

    public RawHttpSocket(Function<String, String> handler) {
        this.handler = handler;
    }

    public static void main(String[] args) throws IOException {
        String body = "<html><head></head><body><pre style=\"word-wrap: break-word; white-space: pre-wrap;\"><h1>Hello world!</h1>\n" +
                "</pre></body></html>";

        RawHttpSocket rawHttpSocket = new RawHttpSocket((str) -> {
            System.out.println(str);
            // 第一個 \n 是header結尾 第二個 \n 是header和body的分段
            return "HTTP/1.1 200 ok\n\n"+body+"\n";
        });
        rawHttpSocket.listener(9000);
    }

    private void listener(int port) throws IOException {
        // 創建ServerSocket,綁定端口
        serverSocket = new ServerSocket(port);
        while (true) {
            // 等待Socket創建鏈接
            Socket socket = serverSocket.accept();
            new Thread(() -> {
                try {
                    // 處理請求
                    this.accpet(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    private void accpet(Socket socket) throws IOException {

        System.out.println("a socket created");

        // 讀取到請求數據
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = "";
        StringBuffer requestBuffer = new StringBuffer();
        // line有可能出現null common-lang3下的工具類:StringUtil
        while (StringUtil.isNotBlank((line = reader.readLine()))) {
            requestBuffer.append(line).append("\n");
        }
        String request = requestBuffer.toString();

        // 返回數據
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        String response = handler.apply(request);
        writer.write(response);
        writer.flush();
        socket.close();
    }

}

HTTP服務

URL

咱們一般經過URL來訪問一個網站,URL也就是咱們所說的統一資源定位符,其中由如下部分構成:

URL分類

像80端口,443端口,URL中的端口號是能夠省略的

DNS解析

也就是域名解析系統,一般當咱們經過URL訪問某一個網站的的時候,經過DNS查詢獲得當前域名所對應的IP地址,而後瀏覽器再經過返回的IP來定位到服務器資源並返回給瀏覽器,這也就是DNS解析的工做原理

可是咱們要想一個問題,到目前爲止,存在了幾十億的網站,並且有時候一個域名下會解析N多個IP地址,這種狀況下,快速解析到IP地址就成爲了一個問題,因而出現了分級緩存策略,其實介紹下來就是這樣的:

  1. 當用戶訪問一個網站的時候,首先會從本地緩存中查找是否存在DNS條目,若是有的話就根據該條目直接訪問;若是沒有的話,回去系統的hosts文件下查找,匹配到就訪問,不然會請求到DNS本地服務商。

這一步的存在會屏蔽掉80%的流量請求出去

  1. 在DNS本地服務商中也會存在緩存,若是這裏也沒有會請求到根服務器中
  2. 根服務器在分佈在全球,並且在其服務器上只存目錄,請求過來以後經過網站域名後綴請求到頂級域名服務器中匹配
  3. 和根服務器同樣,頂級域名服務器上也只存目錄,最終經過頂級域名服務器的匹配將請求轉發到了權威服務器
  4. 在權威服務器中獲得指定的DNS條目,最終返回給客戶端

DNS解析

和CDN技術同樣,根據最優規劃,DNS解析會給出最適合當前客戶端的IP

CDN

CDN技術也是目前架構上使用市場普遍的一種技術,主要能夠用來作:

  • 流量分發

雞蛋不放在同一個籃子裏,一樣的,咱們的應用也不會部署在一塊兒,當咱們的應用分散在各地機房,應用的請求也須要作相應的調整,可讓用戶請求離他們最近的服務器,也能夠提高訪問的效率

  • 數據緩存,包括靜態資源和一致性要求低的動態數據

CDN

  • 不一樣服務器之間存儲的內容都是同樣的(鏡像文件),這樣在訪問的時候才能保證一致性

傳輸控制層經常使用協議

TCP協議

TCP協議面向鏈接的,安全可靠的傳輸協議,而且可以保證數據在傳輸過程當中的完整性

TCP協議若是須要創建鏈接,須要進行三次握手操做:

三次握手

  1. 客戶端發送SYN(同步消息)給服務端,通知服務端準備好進行鏈接,
  2. 服務端接收到客戶端發送的SYN後會把ACK和服務端的SYN消息同時發送給客戶端
  3. 客戶端接收到SYN消息以後再次給服務端發送一個ACK響應消息

三次握手操做,在客戶端的角度上來說:

  1. 驗證了自身的輸入流和輸出流是沒有問題的,
  2. 最後給服務端的響應消息也是明確告知服務端本身收到了響應消息

等到三次握手所有完成以後,應用層纔會開闢線程,開闢對象,開闢文件描述符等等的系統資源

同時,若是客戶端想要和服務端斷開鏈接的話,那麼要經歷四次分手操做:

四次分手

  1. 客戶端發送斷開請求FIN,服務端接收到FIN請求以後會給客戶端返回ACK響應
  2. 服務端通過等待,肯定能夠斷開當前鏈接的時候會給客戶端發送FIN
  3. 客戶端接收到服務端返回的FIN請求,當客戶端處理完以後,就會給服務端發送ACK響應,這時此次的鏈接所有斷開

有商有量,纔是和平分手

在TCP協議中,三次握手,數據傳輸,四次分手三者是不可被分割的最小粒度

UDP協議

相對比TCP協議來說,UDP比TCP簡單了不少,UDP不須要鏈接,這也就形成了它不是安全可靠的鏈接,並且會出現數據包丟失的狀況,可是UDP協議的傳輸速度比TCP快了不少

這種協議適用的場景包括:

  • 音視頻
  • 廣播
  • ...

最後的話

好了,不聊了,這裏欠個債:

網絡層的下一跳機制數據鏈路層的ARP協議,在後面再跟你們聊

駭,感受有點水啊

相關文章
相關標籤/搜索