Socket網絡編程入門

什麼是網絡編程

什麼是網絡?java

在計算機領域中,網絡是信息傳輸、接受、共享的虛擬平臺。編程

經過它把各個點、面、體的信息聯繫到一塊兒,從而實現這些資源的共享。數組

什麼是網絡編程?服務器

網絡編程從大的方面就是說對信息的發送接收。網絡

經過操做相應API調度計算機資源硬件,而且利用管道(網線)進行數據交互的過程。併發

更爲具體的涉及:網絡模型、套接字、數據包。異步

7層網絡模型-OSI

互聯網的本質就是一系列的網絡協議,這個協議就叫OSI協議(一系列協議),按照功能不一樣,分工不一樣,人爲的分層七層。實際上這個七層是不存在的。沒有這七層的概念,只是人爲的劃分而已。區分出來的目的只是讓咱們明白哪一層是幹什麼用的。socket

每一層都運行不一樣的協議。ide

實際上也能夠把它劃成五層、四層。this

七層劃分爲:應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層

五層劃分爲:應用層、傳輸層、網絡層、數據鏈路層、物理層

四層劃分爲:應用層、傳輸層、網絡層、網絡接口層

網絡模型

應用層

用戶使用的都是應用程序,均工做於應用層,你們均可以開發本身的應用程序,數據多種多樣,必須規定好數據的組織形式 。

應用層功能:規定應用程序的數據格式。

好比TCP協議能夠爲各類各樣的程序傳遞數據,好比Email、WWW、FTP等。那麼,必須有不一樣協議規定電子郵件、網頁、FTP數據的格式,這些應用程序協議就構成了」應用層」。

應用層

表示層

表示層的用途是提供一個可供應用層選擇的服務的集合,使得應用層能夠根據這些服務功能解釋數據的含義。表示層如下各層只關心如何可靠地傳輸數據,而表示層關心的是所傳輸數據的表現方式、它的語法和語義。表示服務的例子有統一的數據編碼、數據壓縮格式和加密技術等。

表示層

會話層

會話層任務是:向兩個實體的表示層提供創建和使用鏈接的方法。將不一樣實體之間的表示層的鏈接稱爲會話。所以會話層的任務就是組織和協調兩個會話進程之間的通訊,並對數據交換進行管理。

會話層

傳輸層

傳輸層是通訊子網和資源子網的接口和橋樑,起到承上啓下的做用。

該層的主要任務是:向用戶提供可靠的端到端的差錯和流量控制,保證報文的正確傳輸。傳輸層的做用是向高層屏蔽下層數據通訊的細節,即向用戶透明地傳送報文。

該層常見的協議:TCP/IP中的TCP協議、Novell網絡中的SPX協議和微軟的NetBIOS/NetBEUI協議。

傳輸層提供會話層和網絡層之間的傳輸服務,這種服務從會話層得到數據,並在必要時,對數據進行分割。而後,傳輸層將數據傳遞到網絡層,並確保數據能正確無誤地傳送到網絡層。所以,傳輸層負責提供兩節點之間數據的可靠傳送,當兩節點的聯繫肯定以後,傳輸層則負責監督工做。綜上,傳輸層的主要功能以下:
傳輸鏈接管理:提供創建、維護和拆除傳輸鏈接的功能。傳輸層在網絡層的基礎上爲高層提供面向鏈接面向無鏈接的兩種服務。

傳輸層

網絡層

網絡層的做用是在網絡與網絡相互鏈接的環境中,將數據從發送端主機發送到接受端主機。

舉例:

我在學校教室中,我想找隔壁班的妹子,我通知小弟去告訴她,說有個帥哥找你。而小弟就是網關IP地址就是我所處的教室,MAC地址就是我在教室的某個位置。

網絡層

數據鏈路層、物理層

早期的時候,數據鏈路層就是來對電信號來作分組的。之前每一個公司都有本身的分組方式,很是的亂,後來造成了統一的標準,即以太網協議Ethernet。

通訊傳輸其實是經過物理的傳輸介質實現的。數據鏈路層的做用就是在這些同構傳輸介質互連的設備之間進行數據處理。

物理層中,將數據的 0 、1轉換爲電壓和脈衝光傳輸給物理的傳輸介質,而相互直連的設備之間使用地址實現傳輸。這種地址被稱爲 MAC 地址,也可稱爲物理地址或硬件地址。採用 MAC 地址信息的首部附加到從網絡層轉發過來的數據上,將其發送到網絡。

網絡層與數據鏈路層都是基於目標地址將數據發送給接收端的,可是網絡層負責將整個數據發送給最終目標地址。而數據鏈路層則只負責發送一個分段內的數據。

OSI七層網絡模型 TCP/IP四層概念模型 對應網絡協議
應用層(Application) 應用層 HTTP、TFTP, FTP, NFS, WAIS、SMTP
表示層(Presentation) 應用層 Telnet, Rlogin, SNMP, Gopher
會話層(Session) 應用層 SMTP, DNS
傳輸層(Transport) 傳輸層 TCP, UDP
網絡層(Network) 網絡層 IP, ICMP, ARP, RARP, AKP, UUCP
數據鏈路層(Data Link) 數據鏈路層 FDDI, Ethernet, Arpanet, PDN, SLIP, PPP
物理層(Physical) 數據鏈路層 IEEE 802.1A, IEEE 802.2到IEEE 802.11

OSI的封包與解包過程

OSI七層數據協議數據傳輸時的封包與解包過程

Socket與TCP、UDP

什麼是Socket

  • 簡單來講是IP地址與端口的結合協議(RFC 793)
  • 一種地址與端口的結合描述協議。
  • TCP/IP 協議的相關API的總稱;是網絡API的集合實現。
  • 在計算機通訊領域,Socket 被翻譯爲「套接字」,它是計算機之間進行通訊的一種約定或一種方式。經過 Socket 這種約定,一臺計算機能夠接收其餘計算機的數據,也能夠向其餘計算機發送數據。

Socket的做用與組成

  • 在網絡傳輸中用於惟一標識兩個端點之間的鏈接。
  • 端點:包括(IP + Port)
  • 四個要素:客戶端地址、客戶端端口、服務器地址、服務器端口。

Socket流程

Socket流程

服務器端先初始化Socket,而後與端口綁定(bind),對端口進行監聽(listen),調用accept開始阻塞,等待客戶端鏈接。在這時若是有個客戶端初始化一個Socket,而後鏈接服務器(connect),若是鏈接成功,這時客戶端與服務器端的鏈接就創建了。客戶端發送數據請求,服務器端接收請求並處理請求,而後把迴應數據發送給客戶端,客戶端讀取數據,最後關閉鏈接,一次交互結束。

Socket 之 TCP

  • TCP是面向鏈接的通訊協議
  • 經過三次握手創建鏈接,通信完成時要拆除鏈接

    • 第一次握手:客戶端發送帶有 SYN 標誌的鏈接請求報文段,而後進入 SYN_SEND 狀態,等待服務端確認。
    • 第二次握手:服務端接受到客戶端的 SYN 報文段後,須要發送 ACK 信息對這個 SYN 報文段進行確認。同時,還要發送本身的 SYN 請求信息。服務端會將上述信息放到一個報文段(SYN+ACK 報文段)中,一併發送給客戶端,此時服務端進入 SYN_RECV 狀態。
    • 第三次握手:客戶端接收到服務端的 SYN+ACK 報文段後,會向服務端發送 ACK 確認報文段,這個報文段發送完畢後,客戶端和服務端都進入 ESTABLEISHED 狀態,完成 TCP 三次握手。

      TCP 三次握手

  • 因爲TCP是面向鏈接的因此只能用於端到端的通信。

Socket 之 UDP

  • UDP是面向無鏈接的通信協議。
  • UDP數據包括目標端口號和源端口號信息。
  • 因爲通信不須要鏈接,因此能夠實現廣播發送,並不侷限於端到端。

UDP傳輸

Client-Server Application

  • TCP/IP 協議中,兩個進程間通訊的主要模式爲:CS模型。
  • 主要目的:協同網絡中的計算機資源、服務模式、進程間數據共享。
  • 常見的:HTTPFTPSMTP

Socket TCP 基礎代碼實戰

客戶端代碼:

/**
 * @author Jack
 */
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        // 超時時間
        socket.setSoTimeout(3000);

        // 鏈接本地,端口2000;超時時間3000ms
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), 3000);

        System.out.println("已發起服務器鏈接...");
        System.out.println("客戶端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());
        System.out.println("服務器信息:" + socket.getInetAddress() + " P:" + socket.getPort());

        try {
            // 發送接收數據
            todo(socket);
        } catch (Exception e) {
            System.out.println("異常關閉");
        }

        // 釋放資源
        socket.close();
        System.out.println("客戶端已退出~");

    }

    private static void todo(Socket client) throws IOException {
        // 構建鍵盤輸入流
        InputStream in = System.in;
        BufferedReader input = new BufferedReader(new InputStreamReader(in));

        // 獲得Socket輸出流,並轉換爲打印流
        OutputStream outputStream = client.getOutputStream();
        PrintStream socketPrintStream = new PrintStream(outputStream);

        // 獲得Socket輸入流,並轉換爲BufferedReader
        InputStream inputStream = client.getInputStream();
        BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        boolean flag = true;
        do {
            // 鍵盤讀取一行
            String str = input.readLine();
            // 發送到服務器
            socketPrintStream.println(str);
            // 從服務器讀取一行
            String echo = socketBufferedReader.readLine();
            if ("bye".equalsIgnoreCase(echo)) {
                flag = false;
            } else {
                System.out.println(echo);
            }
        } while (flag);

        // 資源釋放
        socketPrintStream.close();
        socketBufferedReader.close();

    }

}

服務端代碼:

/**
 * @author jack
 */
public class Server {

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);

        System.out.println("服務器準備就緒...");
        System.out.println("服務器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());

        // 等待客戶端鏈接
        for (; ; ) {
            // 獲得客戶端
            Socket client = server.accept();
            // 客戶端構建異步線程
            ClientHandler clientHandler = new ClientHandler(client);
            // 啓動線程
            clientHandler.start();
        }

    }

    /**
     * 客戶端消息處理
     */
    private static class ClientHandler extends Thread {
        private Socket socket;
        private boolean flag = true;

        ClientHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            System.out.println("新客戶端鏈接:" + socket.getInetAddress() + " P:" + socket.getPort());
            try (// 獲得打印流,用於數據輸出;服務器回送數據使用
                 PrintStream socketOutput = new PrintStream(socket.getOutputStream());
                 // 獲得輸入流,用於接收數據
                 BufferedReader socketInput = new BufferedReader(new InputStreamReader(
                         socket.getInputStream()))) {
                do {
                    // 服務器拿到拿到一條數據
                    String str = socketInput.readLine();
                    if ("bye".equalsIgnoreCase(str)) {
                        flag = false;
                        // 回送
                        socketOutput.println("bye");
                    } else {
                        // 打印到屏幕。並回送數據長度
                        System.out.println(str);
                        socketOutput.println("服務器收到了,你發送的長度爲 :" + str.length());
                    }
                } while (flag);
            } catch (Exception e) {
                System.out.println("鏈接異常斷開");
            } finally {
                // 鏈接關閉
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("客戶端已退出:" + socket.getInetAddress() + " P:" + socket.getPort());
        }
    }

}

運行結果:

服務端

客戶端

報文、協議、Mac地址、IP、端口

報文段

  • 報文段是指TCP/IP協議網絡傳輸過程當中,起着路由導航做用。
  • 用於查詢各個網絡路由網段、IP地址、交換協議等IP數據包。
  • 報文在傳輸過程當中會不斷地封裝成分組、包、幀來傳輸。

傳輸協議

  • 協議顧名思義,一種規定,約束。
  • 約定大於配置,在網絡傳輸中依然適用;網絡的傳輸流程是很健壯的穩定的,得益於基礎的協議構成。
  • 簡單來講: A -> B 的傳輸數據,B能識別,反之 B -> A 的傳輸數據 A也能識別,這就是協議。

Mac地址

  • Media Access Control 或者 Medium Access Control。
  • 意譯爲媒體訪問控制,或稱爲物理地址、硬件地址。
  • 用來定義網絡設備位置。
  • 一般被固化在每一個以太網網卡(NIC,Network Interface Card)。MAC(硬件)地址長48位(6字節),採用十六進制格式。
  • 好比:44-45-53-54-00-00 。

    MAC地址及其組成部分

IP地址

  • 互聯網協議地址(Internet Protocol Address)。
  • 是分配給網絡上使用網際協議的設備的數字標籤。
  • 常見的IP地址分爲IPv4,IPv6
  • IP地址由32位二進制數組成,常以XXX.XXX.XXX.XXX形式出現,每組XXX表明小於或等於255的10進制數。
  • IP地址分爲A、B、C、D、E五大類,其中E類屬於特殊保留地址。

IP地址 - IPv4

  • 總數量:4,294,967,296個(即232):42億個;最終於2011年2月3日用盡。
  • 若是主機號都是1,那麼這個地址爲直接廣播地址。
  • IP地址 "255.255.255.255" 爲受限廣播地址。

IP地址 - IPv6

  • 總共有128位長,IPv6地址的表達形式,通常採用32個十六進制。
  • 由兩個邏輯部分組成:一個64位的網絡前綴和一個64位的主機地址,主機地址一般根據物理地址自動生成,叫作EUI-64。
  • 2001:0db8:85a3:0000:1319:8a2e:0370:7344
  • IPv4能夠轉換爲IPv6,但IPv6不必定能轉換爲IPv4。

端口

  • 若是把IP地址比作一間房子,端口就是出入這間房子的門或者窗戶。
  • 外界的信息飛到不一樣窗戶也就是給不一樣的人傳遞信息。
  • 0-49151號端口都是特殊端口。

常見的特殊端口

  • 計算機之間依照互聯網傳輸層 TCP/IP 協議的協議通訊,不一樣協議都對應不一樣的端口。
  • 49152到65535號端口屬於「動態端口」範圍,沒有端口能夠被正式佔用。
相關文章
相關標籤/搜索