1. 程式人生 > >初識http、https、TCP/IP、Socket網路通訊

初識http、https、TCP/IP、Socket網路通訊

網路由下往上分為:  物理層–                      資料鏈路層– 網路層–                       IP協議 傳輸層–                       TCP協議 會話層– 表示層和應用層–           HTTP協議

一、TCP/IP連線

  手機能夠使用聯網功能是因為手機底層實現了TCP/IP協議,可以使手機終端通過無線網路建立TCP連線。TCP協議可以對上層網路提供介面,使上層網路資料的傳輸建立在“無差別”的網路之上。 建立起一個TCP連線需要經過“三次握手”: 第一次握手 客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認; 第二次握手 伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態; 第三次握手 客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。 握手過程中傳送的包裡不包含資料,三次握手完畢後,客戶端與伺服器才正式開始傳送資料。理想狀態下,TCP連線一旦建立,在通訊雙方中的任何一方主動關閉連線之前,TCP 連線都將被一直保持下去。斷開連線時伺服器和客戶端均可以主動發起斷開TCP連線的請求,斷開過程需要經過“四次握手”(過程就不細寫了,就是伺服器和客戶端互動,最終確定斷開).

二、https 與 http

  1. HTTPS
    HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。
    https:URL 表明它使用了HTTP,但HTTPS存在不同於HTTP的預設埠及一個加密/身份驗證層(在HTTP與TCP之間)。
    HTTPS使用埠443,而不是像HTTP那樣適用埠80來和TCP/IP 進行通訊。SSL使用40位關鍵字作為RC4流加密演算法,這對於商業資訊的加密是合適的。HTTPS和SSL支援使用X.509數字認證,如果需要的話使用者可以確認傳送者是誰。
    主要作用分為兩種:

    • 一種是建立一個資訊保安通道,來保證資料傳輸的安全。
    • 另一種就是確認網站的真實性,凡是使用https的網站,都可以通過點選瀏覽器位址列的鎖頭標誌來檢視網站認證之後的真實資訊。也可以通過CA 機構頒發的安全簽章來查詢。
  2. HTTP
    超文字協議(HTTP,HyperText Transfer Protocol)是網際網路上應用最為廣泛的一種網路協議。Http定義了瀏覽器(即全球資訊網客戶程序)怎樣向全球資訊網伺服器請求全球資訊網文件,以及伺服器怎麼把文件傳給瀏覽器。Http是全球資訊網可靠的交換檔案(包括文字、影象、聲音、以及視訊等)的基礎。
    HTTP是一個屬於應用層的面向物件的協議,由於其簡捷、快速的方式,適用於分散式超媒體資訊系統。它於1990年提出,經過幾年的使用與發展,得到不斷地完善和擴充套件。
    HTTP協議的主要特點:

    • 支援C/S(客戶/伺服器)模式。
    • 簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST,每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。
    • 靈活:HTTP允許傳輸任意型別的資料物件。正在傳輸的型別由Content-Type加以標記。
    • 無連線:無連線的含義是限制每次連線只處理一個請求。伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線。採用這種方式可以節省傳輸時間。
    • 無狀態:HTTP協議是無狀態協議,無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。
  3. HTTPS 和 HTTP 的區別
    超文字傳輸協議HTTP協議被用於在Web瀏覽器和伺服器之間傳遞資訊。

    • HTTP協議以明文方式傳送內容,不提供任何方式的資料加密,如果攻擊者截取了Web瀏覽器和網站伺服器之間的傳輸報文,就可以直接讀懂其中的資訊,因此HTTP協議不適合傳輸一些敏感資訊,比如信用卡號、密碼等。
    • 為了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文字傳輸協議HTTPS。為了資料傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證伺服器的身份,併為瀏覽器和伺服器之間的通訊加密。

    HTTPS和HTTP的區別:

    • https 用的 443 埠, http 用的 80 埠
    • 採用 https 的伺服器必須從CA(Certificate Authority)申請一個用於證明伺服器用途型別的證書。
    • http是超文字傳輸協議,資訊是明文傳輸,https 則是具有安全性的ssl加密傳輸協議。
    • http的連線很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路協議,比http協議安全。

三、TCP/IP、Socket網路通訊

  1. 網路間的程序通訊與Socket
    TCP/IP協議族中網路層的IP地址可以唯一標識網路中的主機,而傳輸層的協議+埠可以唯一標識主機中的應用程式(程序)。這樣利用這三元組就可以標識網路的程序了,網路中的程序通訊就可以利用這個標誌與其它程序進行互動。
    Socket通常也稱作”套接字“,用於描述IP地址和埠,是一個通訊鏈的控制代碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。就目前而言,幾乎所有的應用程式都是採用Socket來實現網路程序之間的通訊。
    Socket所支援的協議種類也不光TCP/IP一種,因此兩者之間是沒有必然聯絡的。在Java環境下,Socket程式設計主要是指基於TCP/IP協議的網路程式設計。
  2. TCP、UDP
    TCP是Tranfer Control Protocol的簡稱,是一種面向連線的保證可靠傳輸的協議。通過TCP協議傳輸,得到的是一個順序的無差錯的資料流。傳送方和接收方的成對的兩個socket之間必須建立連線,需要連線時間,以便在TCP協議的基礎上進行通訊。
    優缺點和應用場景:
    (1)可靠穩定,傳遞資料前,會有三次握手建立連線,面向有連線。
    (2)傳遞資料時,有確認、視窗(流量控制)、重傳、擁塞控制。確認機制保證接收端每收到一個正確包都會迴應給傳送端,超時或者資料包不完整的話傳送端會重傳。
    缺點:
    (1)整體來說傳輸慢,效率低,佔用系統資源高。
    (2)傳遞資料前,建立連線需要耗時,傳遞資料時,確認、重傳、擁塞等會消耗大量時間以及CPU和記憶體等硬體資源。
    (3)因為有確認機制、三次握手等機制,容易被人利用,實現DOS 、DDOS攻擊。
    當對網路通訊質量有要求的時候,比如:整個資料要準確無誤的傳遞給對方,這往往用於一些要求可靠的應用,比如HTTP、HTTPS、FTP等傳輸檔案的協議,POP、SMTP等郵件傳輸的協議。

    UDP是User Datagram Protocol的簡稱,是一種無連線的協議,每個資料報都是一個獨立的資訊,包括完整的源地址或目的地址,因此無需建立傳送方和接收方的連線,它在網路上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性、次序性都是不能被保證的。而且被傳輸資料報必須限定在64k以內。

  3. Socket通訊

    1. 利用Socket建立連線的過程
      套接字之間的連線過程分為三個步驟:伺服器監聽,客戶端請求,連線確認。
      (1)伺服器監聽:伺服器端套接字處於等待連線的狀態,實時監控網路狀態,等待客戶端的連線請求。
      (2)客戶端請求:指客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連線的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連線請求。
      (3)連線確認:當伺服器端套接字監聽到或者說接收到客戶端套接字的連線請求時,就響應客戶端套接字的請求,建立一個新的執行緒,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連線。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求。

    2. Socket的Java實現
      服務端:

import java.io.DataInputStream;
          import java.io.DataOutputStream;
          import java.io.IOException;
          import java.net.ServerSocket;
          import java.net.Socket;
          public classSocketManager {
            public static void main(String[] args) {
            SocketManager manager = new SocketManager();
            manager.doListen();
             }
            public void doListen() {
            ServerSocket server;
            try {
                server = new ServerSocket(9991);
                while (true) {
                    Socket client = server.accept();
                    new Thread(new SSocket(client)).start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
           }
          //伺服器程序
           classSSocketimplementsRunnable {
            Socket client;
            public SSocket(Socket client) {
                this.client = client;
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
        public void run() {
            DataInputStream input;
            DataOutputStream output;
            try {
                input = new DataInputStream(client.getInputStream());
                output = new DataOutputStream(client.getOutputStream());
                String listMsg = input.readUTF();
                output.writeUTF("Send : " + listMsg + " \r\n HelloVillage...");
                System.out.println("Recive: " + listMsg);
                listMsg = input.readUTF();
                output.writeUTF("Send Second: " + listMsg + " \r\n HelloVillage...");
                System.out.println("Recive Second: " + listMsg);
            } catch (IOException e) {
                e.printStackTrace();
            }
          }
        }
      }

客戶端:

  import java.io.DataInputStream;
          import java.io.DataOutputStream;
          import java.io.IOException;
          import java.io.OutputStream;
          import java.net.Socket;
          import java.net.UnknownHostException; 
          public classSocketClient {
          public static void main(String[] args) {
            Socket socket = null;
            try {
                socket = new Socket("127.0.0.1", 9991);
                //向伺服器端第一次傳送字串 
                OutputStream netOut = socket.getOutputStream();
                DataOutputStream doc = new DataOutputStream(netOut);
                DataInputStream in = new DataInputStream(socket.getInputStream());
                //向伺服器端第二次傳送字串 
                doc.writeUTF("list");
                String res = in.readUTF();
                System.out.println(res);
                doc.writeUTF("bye");
                res = in.readUTF();
                System.out.println(res);
                doc.close();
                in.close();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                    }
                }
             }
           }
          }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38