Socket網絡編程之基礎入門

目錄

開頭說兩句

一、網絡編程

二、Socket與TCP、UDP

三、Socket TCP案例簡單實現

四、報文、協議、Mac地址

五、IP、端口及遠程服務器


開頭說兩句

國內自年初爆發新冠肺炎疫情到現在,大家應該都是閉門不出吧,各大公司也纔開工不久,我本人疫情這段時期也是一直很忙,從年初四到現在都沒騰出手來做分享,這篇文章是年前就構思了一直到現在才完成,也是無奈之舉,沒辦法,公司做醫療行業的,所以這段時間業務一直不斷,別的不多說了,開始今天的內容——Socket網絡編程。

一、網絡編程

1、什麼是網絡?

在計算機領域中,網絡是信息傳輸、接收、共享的虛擬平臺,通過它可以把各個點、面、體的信息聯繫到一起,從而實現這些資源的共享,網絡是人類發展史以來最重要的發明,提高了科技和人類社會的發展。

2、局域網

我們的電腦、手機、打印機這些東西都連接到一個路由器上,這就稱之爲一個局域網,路由器再通過一根網線到達Modem(就是我們平時所說的貓,學名叫作調制解調器),最終通過光纖或者雙絞線連接到外面的廣域網、因特網,這樣就實現了上網的過程。這裏說明一點,現在的路由器裏面一般都內置了一個Modem的功能,一根網線接到路由器上面,再接到你的電腦,所以上面的圖只是一種情況。

3、互聯網 

每一個星狀的結構可以理解爲是一個局域網,無數個局域網組合起來就是互聯網,同時還包含了廣域網、城域網,這些東西組合之後就是我們的互聯網。

4、什麼是網絡編程

網絡編程從大的方面說就是對信息的發送到接收,通過操作相應Api調度計算機硬件資源,並利用傳輸管道(網線)進行數據交換的過程。舉個栗子:比如在我們做手機開發的過程中,我們手機需要調用服務器端的接口,就實現了把我們的json數據傳輸到後臺去,這就涉及到我們調用的api,這個api調用之後在手機的硬件層面所做的操作對上層而言是屏蔽的,這裏就利用了管道就是網線,當然手機上沒有網線,它是通過無線跟基站進行交互,交換數據之後,基站跟基站之間通過一定的網線來傳輸數據,最終調度到服務器上,這就是一個傳輸的過程。這裏主要涉及兩方,發送方和接收方,發送方可能是json或字符串,想要傳輸就需要轉換成對應的電信號,想要轉換成對應的電信號,就需要一定的加工處理,每一次相對完整的獨立的加工步驟就是一個處理層,後面會說到七層網絡模型。更爲具體的涉及:網絡模型、套接字、數據包。

5、網絡模型

從上面這張圖中我們可以看到,這裏一共是分爲兩部分說明:發送方和接收方

發送方:首先是應用層就是你的應用;假如你的app要傳輸數據,它就需要調用到表示層,表示層其實就是把應用數據表示成對應的數據層面的東西,比如你的字符串要轉換成byte類型的數據,就是需要一定的轉換;接着進入會話層,會話層就是對不同機器之間進行會話管理;接着進入下一層傳輸層,傳輸層就是接收上一層的數據,在必要的時候將數據進行分割,並將這些數據交給網絡層,並且要保證這些數據段的有效性;下一層進入網絡層,它的主要作用就是控制子網的運行,比如邏輯地址進行分組傳輸以及路由的選擇;再後面是數據鏈路層,主要作用是進行物理地址的尋找,同時將原始比特流轉化爲邏輯傳輸路線;最下面就是物理層,它是機械的接口通信上原始的比特流傳輸,就是原始電信號的傳輸,接收方的話就是反過來將原始的電信號或者光信號經過數據鏈路層的轉換依次解析向上傳遞至應用層,總結一下如下:

基礎層:物理層、數據鏈路層、網絡層

傳輸層:TCP-UDP協議層、Socket

高級層:會話層、表示層、應用層

6、網絡模型-對應關係

這張圖最左邊是我們之前看到的七層的OSI模型,往右是TCP/IP協議層,這裏相對於七層網絡模型分的更加廣闊一些,最右邊是細分了每一層都有哪些東西。

二、Socket與TCP、UDP

1、什麼是Socket

簡單來說是IP地址與端口的結合協議(RFC 793),是一種地址與端口的結合描述協議,是TCP/IP協議的相關API的總稱,是網絡Api的集合實現,涵蓋了Stream Socket/Datagram Socket。

2、Socket的作用與組成

在網絡傳輸中用於唯一標示兩個端點之間的鏈接,端點包括IP+Port,有4個要素:客戶端地址、客戶端端口、服務器地址、服務器端口。

3、Socket傳輸原理

這裏可以對應着四大要素看一下,客戶端和服務器各有一個IP地址,然後端口是25號端口,IP+Port就等於Socket協議了,這裏舉例是一個郵件服務器,客戶端通過25號端口去向服務器取郵件,有的話服務器就給客戶端一個返回,這個過程就是socket傳輸原理的過程。

4、Socket之TCP

TCP是面向連接的通信協議,通過三次握手建立連接,通訊完成時要拆除連接,由於TCP是面向連接的所以只能用於端到端通訊。

5、Socket之UDP

UDP是面向無連接的通訊協議,UDP數據包括目的端口號和源端口號信息,由於通訊不需要連接,所以可以實現廣播發送,並不侷限於端到端。

三、Socket TCP案例簡單實現

單純的說理論,有點枯燥乏味,這一部分,使用Socket來簡單的寫個小案例,實現簡單的消息收發流程:

客戶端代碼:

import java.io.*;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * 客戶端
 */
public class Client {

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        //設置超時時間
        socket.setSoTimeout(3000);
        //使用ipv4本機地址,端口2000 超時時間3s
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), 3000);
        System.out.println("連接服務器------");
        System.out.println("客戶端信息:地址:" + socket.getLocalAddress() + ",端口:" + socket.getLocalPort());
        System.out.println("服務器信息:地址:" + socket.getInetAddress() + ",端口:" + socket.getPort());

        try {
            sendMessage(socket);
        } catch (Exception e) {
            System.out.println("異常關閉");
        }

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

    //發送數據
    private static void sendMessage(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輸入流,並轉換爲BufferReader
        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 ("exit".equalsIgnoreCase(echo)) {
                flag = false;
            } else {
                System.out.println(echo);
            }
        } while (flag);

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

}

服務端代碼:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服務器端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        //監聽2000端口
        ServerSocket server = new ServerSocket(2000);

        System.out.println("服務器準備就緒------");
        System.out.println("服務器信息:地址" + server.getInetAddress() + ",端口:" + server.getLocalPort());

        //等待客戶端連接,構建一個無限循環
        for (;;) {
            //得到客戶端
            Socket client = server.accept();
            //客戶端構建異步線程
            ClientHandler handler = new ClientHandler(client);
            //啓動異步線程
            handler.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() + ",端口:" + socket.getPort());
            try {
                //得到打印流,用於數據輸出;服務器回送數據使用
                PrintStream socketOutput = new PrintStream(socket.getOutputStream());
                //得到輸入流,用於接收數據
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                do {
                    //客戶端拿到一條數據
                    String str = socketInput.readLine();
                    if ("exit".equalsIgnoreCase(str)) {
                        flag = false;
                        //回送
                        socketOutput.println("exit");
                    } else {
                        //打印到屏幕,並回送數據長度
                        System.out.println(str);
                        if (str.equalsIgnoreCase("我是客戶端")){
                            socketOutput.println("我是服務端");
                        }else {
                            socketOutput.println("回送客戶端消息長度--->"+str.length());
                        }
                    }
                } while (flag);
                socketInput.close();
                socketOutput.close();
            } catch (Exception e) {
                System.out.println("連接異常斷開");
            } finally {
                //連接關閉
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("客戶端已退出!地址:" + socket.getInetAddress() + ",端口:" + socket.getPort());
        }
    }
}

運行結果如下:這裏開了兩個窗口,方便操作和查看,左側是服務端,右側是客戶端,整個流程跟我們代碼中設計的是完全一致的,不同的客戶端端口是不一致的,單個客戶端退出時,服務端仍然保持着連接狀態,等待其它客戶端連接。

四、報文、協議、Mac地址

1、報文段

報文段是指TCP/IP協議網絡傳輸過程中,起着路由導航作用,用以查詢各個網絡路由網段、IP地址、交換協議等IP數據包,報文段充當整個TCP/IP協議數據包的導航路由功能,報文在傳輸過程中會不斷地封裝成分組、包、幀來傳輸,封裝的方式就是添加一些控制信息組成的首部,即報文頭。

2、傳輸協議

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

3、Mac地址

Media Access Control或者Medium Access Control;意譯爲媒體訪問控制,或稱爲物理地址、硬件地址,用來定義網絡設備的位置,形如:44-45-53-54-00-00,與身份證類似,例如下圖中的地址:

五、IP、端口及遠程服務器

1、IP地址

互聯網協議地址(英文:Internet Protocol Address,又譯爲網際協議地址),縮寫爲IP地址(英文:IP Address),是分配給網絡上使用網際協議的設備的數字標籤,常見的IP地址分爲IPV4和IPV6兩大類。

IPV4:IP地址由32位二進制數組成,常以xxx.xxx.xxx.xxx形式表現,每組xxx代表小於或等於255的十進制數,比如:208.80.152.2。分爲A、B、C、D、E五大類,其中E類屬於特殊保留地址,總數量42億個,在2011/02/03日用盡。如果主機號全部是1,那麼這個地址爲直接廣播地址,如果全部是255,則是受限廣播地址。

IPV6:總共有128位長,表現形式一般是採用32個十六進制數表示,由兩個邏輯部分組成:一個64位的網絡前綴和一個64位的主機地址,主機地址通常根據物理地址自動生成,叫做EUI-64(或者64位擴展唯一標識),例如:2001:0db8:85a3:0000:1319:8a2e:0370:7344,IPV4轉換爲IPV6一定可以,IPV6轉IPV4不一定可以。

2、端口

如果把IP地址比作一間房子,端口就是門或者窗戶,0-1023號端口以及1024-49151號端口都是特殊端口

計算機之間依照互聯網傳輸層TCP/IP協議的協議通信,不同的協議都對應不同的端口,49152-65535號端口屬於“動態端口”,沒有端口可以被正式的註冊佔用

3、遠程服務器

局域網:一般來說,家裏的環境以及公司相互電腦之間環境都屬於局域網,我與你的電腦之間屬於互聯網,而非局域網,默認我的電腦無法直接鏈接到你的電腦,連接示意圖如下:

Web請求流程如下:

寫到這裏就簡單的把Socket的基本概念和使用說完了,這一個系列內容還是很多的,邊學邊做筆記吧,路漫漫其修遠兮,必將上下而求索,加油,各位!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章