UDP數據報套接字編程入門

目錄

1.TCP和UDP的特點及區別

1.1TCP的特點

?1.2UDP的特點

?1.3區別

2.UDP Socket的api的介紹

2.1DatagramSocket API

2.2DatagramPacket API ?

3.回顯客戶端與服務器

3.1回顯服務器

3.1.1UdpEchoServer類的創建

3.1.2服務器的運行方法start()

3.1.3main部分

?3.1.4.完整代碼

?3.2回顯客戶端

3.2.1UdpEchoClient類的創建

?3.2.2客戶端的運行方法start()

3.2.3main部分?

3.2.4?完整代碼


1.TCP和UDP的特點及區別

想要進行網絡編程,都需要使用到系統的API。本質上都是傳輸層提供的。傳輸層涉及到的協議主要有兩個。TCP和UDP,他倆的api差異很大。

TCP和UDP都是Socket套接字針對的傳輸層協議劃。

Socket 套接字,是由系統提供用于網絡通信的技術,是基于 TCP/IP 協議網絡通信的基本操作單元。基 于Socket 套接字的網絡程序開發就是網絡編程

1.1TCP的特點

流套接字 :使用傳輸層 TCP 協議 ?
以下為TCP的特點
1.有連接
2.可靠傳輸
3.面向字節流
4.有接收緩沖區,也有發送緩沖區
5.大小不限
對于字節流來說,可以簡單的理解為,傳輸數據是基于 IO 流,流式數據的特征就是在 IO 流沒有關閉的情 況下,是無邊界的數據,可以多次發送,也可以分開多次接收。

?1.2UDP的特點

數據報套接字:使用傳輸層UDP協議

以下為UDP的特點

1.無連接
2.不可靠傳輸
3.面向數據報
4.有接收緩沖區,無發送緩沖區
5.大小受限:一次最多傳輸 64k

?1.3區別

(1)有/無 連接

網絡中談到的連接,本質上是通信雙方各自保存雙方信息。

有連接是通信雙方都要同意。如:微信發電話。

無連接是收方無論是否同意,都會收到信息。如:微信發消息。

(2)可/不可 靠傳輸

由于網絡上存在的異常情況非常的多,無法保證網絡數據100%通信成功。

可靠傳輸 是指發送方知道自己發送的信息是否成功送達。反之不知道則是不可靠傳輸

(3)?面向數據報/字節流

指的是網絡中傳輸的基本單位是數據報/字節流。


2.UDP Socket的api的介紹

2.1DatagramSocket API

DatagramSocket UDP Socket,用于發送和接收UDP數據報。

socket 文件抽象了“網卡”這樣的硬件設備。

(1)DatagramSocket 構造方法:

?(2)DatagramSocket 方法:

2.2DatagramPacket API ?

DatagramPacketUDP Socket發送和接收的數據報。?

(1)DatagramPacket 構造方法:

?(2)DatagramPacket 方法:

構造UDP發送的數據報時,需要傳入 SocketAddress ,該對象可以使用 InetSocketAddress 來創建。

InetSocketAddress API
InetSocketAddress SocketAddress 的子類 )構造方法:


3.回顯客戶端與服務器

什么叫回顯客戶端與與服務器呢?

其實就是:客戶端向服務端發送請求,一般來說我們的服務端會對我們發送的請求進行處理,我們這里為了簡單,就省略里面的處理過程,只實現將請求重新發回客戶端,不做任何處理。

3.1回顯服務器

3.1.1UdpEchoServer類的創建

1.需要創建一個DatagramSocket對象,因為需要操作網卡。

代碼:

public class UdpEchoServer {private DatagramSocket socket=null;public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);}
}

代碼說明:

(1)socket=new DatagramSocket(port);

在運行一個服務器的時候,通常會手動指定一個端口號。

補:一個主機上的端口號,只能被一個進程綁定,但一個進程可以綁定多個端口號。?

(2)throws SocketException

通常表示socket創建失敗。

比如:端口號已經被別的進程占用了。

3.1.2服務器的運行方法start()

工作內容:

1. 讀取請求并解析

2. 根據請求計算響應 (對于 回顯服務器來說, 這一步啥都不用做)

3. 把響應返回到客戶端.

4.打印日志

?代碼:

import java.io.IOException;
import java.net.*;public class UdpEchoServer {private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() throws IOException {System.out.println("服務器啟動");while (true) {DatagramPacket requestpacket = new DatagramPacket(new byte[4096], 4096);socket.receive(requestpacket);String request = new String(requestpacket.getData(), 0, requestpacket.getLength());String response = process(request);DatagramPacket responsepacket = new DatagramPacket(response.getBytes(), response.getBytes().length, requestpacket.getSocketAddress());socket.send(responsepacket);// 打印日志System.out.printf("[%s:%d] req: %s, resp: %s\n", requestpacket.getAddress().toString(),requestpacket.getPort(), request, response);}}private String process(String request) {return request;}
}

代碼說明:

1.? while (true) {~~~}

對于服務器來說,需要不停的收到請求,返回響應,收到請求,返回響應

2.? ??DatagramPacket requestpacket = new DatagramPacket(new byte[4096], 4096);

(1)byte[4096]->4096 表示的是載荷長度。

這個數組存的是消息正文(應用層數據包)也就是UDP數據包載荷部分。

(2)?socket.receive(requestpacket);

如果執行到socket.receive(requestpacket)的時候,還沒有客戶端發來請求,則會先堵塞等待。

(3 )requestpacket.getSocketAddress()

由于requestpacket是從客戶端來的數據報,故得到的InetAddress對象就會包含了客戶端的IP和端口號。

3.1.3main部分

代碼:

public static void main(String[] args) throws IOException {UdpEchoServer server = new UdpEchoServer(9090);server.start();}

代碼說明:

UdpEchoServer server = new UdpEchoServer(9090);

9090->這個端口號可以指定任何你想要指定的端口號。

?3.1.4.完整代碼

代碼:

package network;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class UdpEchoServer {private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}// 服務器的啟動邏輯.public void start() throws IOException {System.out.println("服務器啟動!");while (true) {// 每次循環, 就是處理一個請求-響應過程.// 1. 讀取請求并解析DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);// 讀到的字節數組, 轉成 String 方便后續的邏輯處理.String request = new String(requestPacket.getData(), 0, requestPacket.getLength());// 2. 根據請求計算響應 (對于 回顯服務器來說, 這一步啥都不用做)String response = process(request);// 3. 把響應返回到客戶端.//    構造一個 DatagramPacket 作為響應對象DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);// 打印日志System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),requestPacket.getPort(), request, response);}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer server = new UdpEchoServer(9090);server.start();}
}

?3.2回顯客戶端

3.2.1UdpEchoClient類的創建

代碼:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;public UdpEchoClient(String serverIp,int serverPort) throws SocketException {this.socket = new DatagramSocket();this.serverIp = serverIp;this.serverPort = serverPort;}
}

?代碼說明:

(1)this.socket = new DatagramSocket();

客戶端這邊一般不會手動指定端口好,會讓系統自動分配一個端口號。

(2)private String serverIp;
? ? ? ? ?private int serverPort;?

? 客戶端需要主動給服務器發送請求,發送請求的前提是知道服務器在哪。

?3.2.2客戶端的運行方法start()

工作內容:

1. 從控制臺讀取要發送的請求數據.

2. 構造請求并發送

3. 讀取服務器的響應.

4. 把響應顯示到控制臺上

代碼:

 public void start() throws IOException {System.out.println("客戶端啟動");Scanner scanner = new Scanner(System.in);while (true){System.out.print("->");if(!scanner.hasNext()){break;}String request=scanner.next();DatagramPacket requestpacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);socket.send(requestpacket);DatagramPacket responsepacket=new DatagramPacket(new byte[4096],4096);socket.receive(responsepacket);String response=new String(responsepacket.getData(),0,responsepacket.getLength());System.out.println(response);}}

??代碼說明:

InetAddress.getByName(serverIp)

把數據的單位從字符->字節。

3.2.3main部分?

代碼:

    public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);client.start();}
3.2.4?完整代碼

代碼:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;// 此處 ip 使用的字符串, 點分十進制風格. "192.168.2.100"public UdpEchoClient(String serverIp, int serverPort) throws SocketException {this.serverIp = serverIp;this.serverPort = serverPort;socket = new DatagramSocket();}public void start() throws IOException {System.out.println("客戶端啟動");Scanner scanner = new Scanner(System.in);while (true) {// 要做四個事情System.out.print("-> "); // 表示提示用戶接下來要輸入內容.// 1. 從控制臺讀取要發送的請求數據.if (!scanner.hasNext()) {break;}String request = scanner.next();// 2. 構造請求并發送.DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,InetAddress.getByName(serverIp), serverPort);socket.send(requestPacket);// 3. 讀取服務器的響應.DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);socket.receive(responsePacket);// 4. 把響應顯示到控制臺上.String response = new String(responsePacket.getData(), 0, responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);// UdpEchoClient client = new UdpEchoClient("139.155.74.81", 9090);client.start();}
}

運行結果:

?

小結?:


以上為我個人的小分享,如有問題,歡迎討論!!!?

都看到這了,不如關注一下,給個免費的贊?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/710608.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/710608.shtml
英文地址,請注明出處:http://en.pswp.cn/news/710608.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# CAD PaletteSet.Style各種外觀和行為樣式

ps.Style 是 Autodesk.AutoCAD.Windows.PaletteSet 類的一個屬性,用于定義調色板集(PaletteSet)的各種外觀和行為樣式。它可以是 PaletteSetStyles 枚舉類型的組合值 PaletteSetStyles 枚舉中包含以下一些選項: NameEditable&am…

統計子矩陣

一、題目描述 P8783 [藍橋杯 2022 省 B] 統計子矩陣 二、算法簡析 2.1 二維前綴和 我們知道,只要確定了矩陣的左上頂點和右下頂點,一個矩陣就被固定了。因此,我們可以遍歷這兩個頂點,達到遍歷所有子矩陣的目的,復雜…

AutoSAR(基礎入門篇)12.5-Dem

目錄 一、Dem簡介 二、Dem消抖 1、計數模式 1. 普通增減計數 2. 反向歸零增減模式

在微服務整合dubbo,以為微服務版的若依為例

在微服務整合dubbo,以為微服務版的若依為例 一、環境二、整合過程1、父模塊依賴2、生產者3、消費者 三、修改若依的服務調用方式為dubbo1、改造系統模塊2、改造認證授權中心 四、整合過程遇到的問題1、出現循環引用2、出現依賴沖突3、啟動出現端口號被占用4、出現某…

UVa11726 Crime Scene

題目鏈接 UVa11726 - Crime Scene 題意 給定n(n≤100)個物體,每個物體都是一個圓或者k(k≤10)邊形,用長度盡量小的繩子把它們包圍起來。 分析 孟加拉國Manzurur Rahman Khan (Sidky)大神出的難題&#xff…

MySQL 核心模塊揭秘 | 07 期 | 二階段提交 (1) prepare 階段

二階段提交的 prepare 階段,binlog 和 InnoDB 各自會有哪些動作? 本文基于 MySQL 8.0.32 源碼,存儲引擎為 InnoDB。 1. 二階段提交 二階段提交,顧名思義,包含兩個階段,它們是: prepare 階段。…

springboot-基礎-eclipse配置+helloword示例

備份筆記。所有代碼都是2019年測試通過的,如有問題請自行搜索解決! 下一篇:springboot-基礎-添加model和controller的簡單例子常用注解含義 目錄 配置helloword示例新建項目創建文件 配置 spring boot官方有定制版eclipse,也就是…

BUUCTF AWD-Test1

打開靶場是這個有些簡陋的界面。 隨便點點,找到這個東西。 看到ThinkPHP,思路瞬間清晰,老熟人了。這個就是ThinkPHP漏洞。根據版本我們去找一下poc。 /index.php/?sIndex/\think\View/display&content%22%3C?%3E%3C?php%20phpinfo();…

SHELL 腳本: 導出NEO4j DUMP并上傳SFTP

前提 開通sftp賬號 安裝expect 示例 NEO4J_HOME/path/to/neo4j # neo4j 安裝目錄 DUMP_PATH/data/dump # DUMP本地保存目錄 DUMP_FILEneo4j_$(date %F).dump #導出文件名稱 UPLOAD_DIR/path/to/stfp/dump/ #上傳目錄 $NEO4J_HOME/bin/neo4j-admin dump --databaseneo4j --t…

Vue-5

Vue 3 的優勢 更容易維護(組合式API)更快的速度更小的體積更優的數據響應 創建 Vue 3 項目 前提環境條件:已安裝 16.0 或更高版本的 Node.js node -v創建一個 Vue 應用(下面的指令將會安裝并執行 create-vue ) np…

服務端向客戶端推送數據的實現方案

在日常的開發中,我們經常能碰見服務端需要主動推送給客戶端數據的業務場景,比如數據大屏的實時數據,比如消息中心的未讀消息,比如聊天功能等等。 本文主要介紹SSE的使用場景和如何使用SSE。 服務端向客戶端推送數據的實現方案有哪…

MySQL 自增列解析(Auto_increment)

MySQL數據庫為列提供了一種自增屬性,當列被定義為自增時。Insert語句對該列即使不提供值,MySQL也會自動為該列生成遞增的唯一標識,因此這個特性廣泛用于主鍵的自動生成。 一、自增列的用法 自增列具有自動生成序列值,整型&#…

職責鏈模式(Chain of Responsibility Pattern)

定義 職責鏈模式(Chain of Responsibility Pattern)是一種行為設計模式,它允許對象接收請求并將其沿著處理者鏈傳遞,直到有一個處理者處理它為止。職責鏈模式通過將請求的處理邏輯分布 在職責鏈模式中,通常包含以下幾…

MYSQL04高級_邏輯架構剖析、查詢緩存、解析器、優化器、執行器、存儲引擎

文章目錄 ①. 邏輯架構剖析②. 服務層 - 查詢緩存③. 服務層 - 解析器④. 服務層 - 優化器⑤. 服務層 - 執行器⑥. MySQL8執行原理 ①. 邏輯架構剖析 ①. 服務器處理客戶端請求 ②. 連接層 系統(客戶端)訪問MySQL服務器前,做的第一件事就是建立TCP連接經過三次握手建立連接成…

Linux使用C語言實現通過互斥鎖限制對共享資源的訪問

互斥鎖限制共享資源的訪問 主線程中有兩個線程&#xff0c;分別輸出信息。 #include <stdio.h> #include <pthread.h> #include <unistd.h>int g_data0;void* fun1(void *arg) {printf("t1&#xff1a;%ld thread is create\n", (unsigned long)…

大宋咨詢數據研究在汽車新品上市中的核心作用

隨著汽車行業的快速變革&#xff0c;數據研究已經成為新品上市流程中的不可或缺的一環。從市場定位、產品規劃到營銷策略&#xff0c;數據研究不僅為汽車企業提供了獨特的洞察&#xff0c;還為其提供了決策依據&#xff0c;確保新品在競爭激烈的市場中取得優勢。在這一領域&…

Kubernetes IoTDB系列 | IoTDB搭建 | v1.3.0

目錄 一、IoTDB 介紹二、k8s 部署 IoTDB一、IoTDB 介紹 IoTDB 是一種面向物聯網(IoT)場景的開源時序數據庫。它專門設計用于高效地存儲和查詢大規模物聯網設備產生的時序數據。IoTDB 提供了高吞吐量、低延遲、靈活的數據模型以及多種數據查詢和存儲引擎等特性,使其成為處理…

稀疏圖帶負邊的全源最短路Johnson算法

BellmanFord算法 Johnson算法解決的問題 帶負權的稀疏圖的全源最短路 算法流程 重新設置的每條邊的權重都大于或等于0&#xff0c;跑完Djikstra后得到的全源最短路&#xff0c;記得要還原&#xff0c;即&#xff1a;f(u,v) d(u,v) - h[u] h[v] 例題

45、WEB攻防——通用漏洞PHP反序列化POP鏈構造魔術方法原生類

文章目錄 序列化&#xff1a;將java、php等代碼中的對象轉化為數組或字符串等格式。代表函數serialize()&#xff0c;將一個對象轉換成一個字符&#xff1b;反序列化&#xff1a;將數組或字符串等格式還成對象。代表函數unserialize()&#xff0c;將字符串還原成一個對象。 P…

MWC 2024丨Smart Health搭載高通Aware平臺—美格發布智能健康看護解決方案,開啟健康管理新體驗

2月29日&#xff0c;在MWC 2024世界移動通信大會上&#xff0c;全球領先的無線通信模組及解決方案提供商——美格智能正式發布了新一代Cat.1模組SLM336Q&#xff0c;是中低速物聯網應用場景的高性價比之選。本次還發布了首款搭載高通Aware?平臺的智能看護解決方案MC303&#x…