終於把 TCP 與 UDP 協議整明白了!

網絡編程有三個要素,分別是IP地址、端口號和通訊協議,那本文主要講述的是TCP與UDP這兩種通訊協議,以及編程的實現。java

首先,咱們須要瞭解一下IP地址、端口號、通訊協議的相關知識。面試

1、IP地址

網絡中的計算機使用IP地址來進行惟一標識,IP地址有IPv4和IPv6兩種類型。IPv4採用十進制或二進制表示形式,十進制是一種比較經常使用的表示形式,如192.168.1.131,IPv6採用十六進制表示形式,通常不經常使用。spring

如何查看IP地址相關信息:數據庫

在Windows系統下,打開cmd,輸入命令ipconfig,按回車便可查看。在Linux或Mac系統下,打開終端,使用ifconfig命令,按回車便可查看。編程

2、端口號

端口號是計算機中的應用程序的一個整數數字標號,用來區分不一樣的應用程序。數組

0 ~ 1024 爲被系統使用或保留的端口號,0 ~ 65535爲有效的端口號,也就是說咱們要對一些程序定義端口號的時候,要選擇1024 ~ 65535範圍內的整數數字。安全

好比,之前學過的MySQL的端口號是3306,SQLServer的端口號是1433,查了一下Oracle的端口號是1521。服務器

必定要把這些數據庫對應的端口號,藏在深深的腦海裏,之後在鏈接數據庫的時候,會使用到端口號。網絡

3、通訊協議

說的通俗一點,通訊協議就是網絡通訊中的規則,分爲TCP協議和UDP協議兩種。intellij-idea

第一種:TCP協議

英文名:Transmission Control Protocol 中文名:傳輸控制協議 協議說明:TCP是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議。

舉例:打電話,須要雙方都接通,才能進行對話

特色:效率低,數據傳輸比較安全

第二種:UDP協議

英文名:User Datagram Protocol 中文名:數據報協議 協議說明:UDP是一種面向無鏈接的傳輸層通訊協議。

舉例:發短信,不須要雙方創建鏈接,But,數據報的大小應限制在64k之內

特色:效率高,數據傳輸不安全,容易丟包

4、三要素關係圖與網絡模型圖

一、網絡編程三要素關係圖

注:圖中端口號、IP地址爲演示,並不是真實

二、OSI參考模型與TCP/IP參考模型

5、TCP編程

TCP是基於字節流的傳輸層通訊協議,因此TCP編程是基於IO流編程。

對於客戶端,咱們須要使用Socket類來建立對象。對於服務器端,咱們須要使用ServerSocket來建立對象,經過對象調用accept()方法來進行監聽是否有客戶端訪問。

客戶端與服務器端圖解:

客戶端與服務器端實現步驟:

前提:建立一個項目,在項目中建立兩個模塊(model),一個模塊用來放客戶端相關代碼,一個模塊用來放服務器端相關代碼。

目錄結構以下圖

客戶端

一、建立Socket對象,並指定服務器端應用程序的端口號和服務器端主機的IP地址。

二、使用Socket的對象調用getOutputStream()方法來獲取字節輸出流對象。

三、調用字節輸出流的write(byte[] buf)或者write(int b)向服務器發送指定數據。

四、記得關閉流。

服務器端

一、建立ServerSocket對象,並指定該應用程序的端口號,端口號必須和客戶端指定的端口號同樣。

二、使用ServerSocket對象的accept()方法來監聽客戶端發送過來的請求,返回值爲Socket對象。

三、調用Socket對象的getInputStream()方法獲取字節輸入流對象

四、調用字節輸入流對象的read(byte[] buf)read()方法獲取數據。

五、記得關閉流。

實例

客戶端向服務器端發送信息,並顯示在服務器端。

Client類(客戶端)

package cn.tkrnet.client;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws IOException {
        
        //建立Socket對象,指定要發送到服務器端的IP地址,以及服務器端應用程序接收的端口號
        //localhost表明本機IP地址
        Socket client = new Socket("localhost",9000);
        
        //獲取輸出流,用於向服務器端發送數據
        OutputStream os = client.getOutputStream();
        
        os.write("Java is my friend !".getBytes());
        System.out.println("信息已發送");

        //關閉流
        os.close();
        client.close();
    }
}

Server類(服務器端)

package cn.tkrnet.server;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        System.out.println("--服務器端已開啓--");

        //建立ServerSocket對象,這裏的端口號必須與客戶端的端口號相同
        ServerSocket server = new ServerSocket(9000);

        //調用方法accept(),用來監聽客戶端發來的請求
        Socket socket = server.accept();

        //獲取輸入流對象
        InputStream is = socket.getInputStream();

        //讀取輸入流中的數據
        int b = 0;
        while ((b =is.read()) != -1){
            System.out.print((char)b);
        }
        //關閉流
        is.close();
        socket.close();
        server.close();
    }
}

提示:在運行程序時,必定要先運行服務器端的程序代碼,再運行客戶端的程序代碼。由於客戶端要向服務器發送請求,前提是服務器端要處於開啓狀態。

Server類(服務器端)運行結果:

--服務器端已開啓--

Client類(客戶端)運行結果:

信息已發送

Client類(客戶端)運行後,Server類(服務器端)收到信息,運行結果:

--服務器端已開啓--
Java is my friend !

實例分析:

服務器端啓動後,服務器端的accept()方法一直處於監聽狀態,直到客戶端鏈接了服務器,服務器端再從流中讀取客戶端發來的數據。

恕我直言,這是一個超級無敵簡單的單向通訊實例。

6、UDP編程

UDP使用數據報進行數據傳輸,沒有客戶端與服務器端之分,只有發送方與接收方,二者哪一個先啓動都不會報錯,可是會出現數據丟包現象。發送的內容有字數限制,大小必須限制在64k之內。

發送方與接收方實現步驟:

前提:建立一個項目,在項目中建立兩個模塊(model),一個模塊用來放發送方相關代碼,一個模塊用來放接收方相關代碼。

目錄結構以下圖

發送方

一、建立DatagramSocket對象,能夠指定應用程序的端口號,也能夠不指定。

二、準備須要發送的數據

三、建立DatagramPacket對象,用來對發送的數據進行打包,須要指定發送內容、發送多少、發送到哪裏和接收方的端口號四個參數。

四、調用DatagramSocket對象的send()方法發送數據。

五、記得關閉流。

接收方

一、建立DatagramSocket對象,指定接收方的端口號,這個必須指定。

二、建立一個byte類型數組,用來接收發送方發送過來的數據。

三、建立DatagramPacket對象,準備接收數據。

四、調用DatagramSocket對象的receive()方法用於接收數據。

五、使用String類的構造方法將byte類型的數組中的數據轉化成String類型並顯示。

六、記得關閉流。

實例

發送方發送信息,接收方接收信息,並顯示。

Sender類(發送方)

package cn.tkrnet.Sender;

import java.io.IOException;
import java.net.*;

public class Sender {
    public static void main(String[] args) throws IOException {

        //建立接受或發送的數據報套接字,並指定發送方的端口號爲7770
        DatagramSocket ds = new DatagramSocket(7770);   //端口號也能夠不指定
        System.out.println("---發送方---");

        //建立數據報對象,用來發送數據
        byte[] b = "Java is my friend !".getBytes();

        //8800爲接收方的端口號,netAddress.getByName("localhost")是獲取主機的IP地址
        DatagramPacket dp = new DatagramPacket(b,b.length, InetAddress.getByName("localhost"),7788);

        ds.send(dp);    //發送數據報
        System.out.println("數據已發送");
        //關閉流
        ds.close();
    }
}

Receiver類(接收方)

package cn.tkrnet.receiver;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receiver {
    public static void main(String[] args) throws IOException {
        System.out.println("---接收方---");

        //建立數據報套接字對象,指定的端口號要和發送方發送數據的端口號相同
        // (不是發送方的端口號7770,是發送方發送數據的端口號7788)
        DatagramSocket ds = new DatagramSocket(7788);

        //建立接收數據報的對象
        byte[] b = new byte[1024];
        DatagramPacket dp = new DatagramPacket(b,b.length);

        //接收數據
        ds.receive(dp);
        System.out.println(new String(b,0,dp.getLength()));
        //關閉流
        ds.close();
    }
}

提示:在運行程序時,先運行發送方程序,仍是先運行接收方程序都不會報錯,可是有可能會出現數據丟包,通常咱們都先運行接收方的程序代碼,再運行發送方的程序代碼。

Receiver類(接收方)運行結果:

---接收方---

Sender類(發送方)運行結果:

---發送方---
數據已發送

Sender類(發送方)運行後,Receiver類(接收方)接收到信息,運行結果:

---接收方---
    Java is my friend !

實例分析:

只有接收方先啓動運行,纔會存在端口號爲7788的程序,發送方纔能發送數據到指定端口號7788,接收方纔能接收數據。

不瞞你說,這也是個超級無敵簡單的單向通訊實例。

7、總結

以上是我分享給你們的關於網絡通訊TCP協議與UDP協議的一些總結。

若是以爲還不錯的話,就點個贊和在看吧!

原文連接:https://blog.csdn.net/m0_4789...

版權聲明:本文爲CSDN博主「酷酷的猿」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連接及本聲明。

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2021最新版)

2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!

3.阿里 Mock 工具正式開源,幹掉市面上全部 Mock 工具!

4.Spring Cloud 2020.0.0 正式發佈,全新顛覆性版本!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

以爲不錯,別忘了隨手點贊+轉發哦!

相關文章
相關標籤/搜索