新冠病毒的最新動態(tài)廣州seo網(wǎng)站公司
歡迎瀏覽高耳機的博客
希望我們彼此都有更好的收獲
感謝三連支持!??
????????在網(wǎng)絡(luò)編程中,Echo Server 和 Echo Client 回顯是一種經(jīng)典的示例,用于演示基本的網(wǎng)絡(luò)通信。Echo Server 接收來自客戶端的數(shù)據(jù),并將相同的數(shù)據(jù)發(fā)送回客戶端。這種模式在測試網(wǎng)絡(luò)連接和理解網(wǎng)絡(luò)通信原理時非常有用。在這篇文章中,我們將使用 Java 語言來實現(xiàn)基于 UDP 協(xié)議的 Echo Server 和 Echo Client。?
目錄
UDP 協(xié)議概述
API介紹?
Echo Server 實現(xiàn)
服務(wù)器核心流程
服務(wù)器代碼詳解?
Echo Client 實現(xiàn)
客戶端核心流程
客戶端代碼詳解?
運行演示?
?
UDP 協(xié)議概述
UDP(User Datagram Protocol)是一種無連接的網(wǎng)絡(luò)協(xié)議,它在 IP 協(xié)議的基礎(chǔ)上提供一種快速、簡單的數(shù)據(jù)傳輸服務(wù)。與 TCP 協(xié)議不同,UDP 不建立連接,不保證數(shù)據(jù)的可靠傳輸,因此適用于對實時性要求高、可以容忍一定數(shù)據(jù)丟失的應(yīng)用場景,如視頻會議、在線游戲等。
API介紹?
DatagramSocket 是UDP Socket,用于發(fā)送和接收UDP數(shù)據(jù)報。?
構(gòu)造方法:
方法簽名 | 方法說明 |
DatagramSocket() | 創(chuàng)建一個UDP數(shù)據(jù)報套接字的Socket,綁定到本機任意一個隨機端口(一般用于客戶端) |
DatagramSocket(int port) | 創(chuàng)建一個UDP數(shù)據(jù)報套接字的Socket,綁定到本機指定的端口(一般用于服務(wù)端)? |
方法:
方法簽名 | 方法說明 |
void receive(DatagramPacket p) | 從此套接字接收數(shù)據(jù)報(如果沒有接收到數(shù)據(jù)報,該方法會阻塞等待) |
void send(DatagramPacket p) | 從此套接字發(fā)送數(shù)據(jù)報包(不會阻塞等待,直接發(fā)送) |
void close() | 關(guān)閉此數(shù)據(jù)報套接字 |
?
DatagramPacket 是UDP Socket發(fā)送和接收的數(shù)據(jù)報。
構(gòu)造方法:
方法簽名 | 方法說明 |
DatagramPacket(byte[] buf, int length) | 構(gòu)造一個DatagramPacket用來接收數(shù)據(jù)報,接收的數(shù)據(jù)保存在字節(jié)數(shù)組(第一個參數(shù)buf)中,接收指定長度(第二個參數(shù)length) |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) | 構(gòu)造一個DatagramPacket用來發(fā)送數(shù)據(jù)報,發(fā)送的數(shù)據(jù)為字節(jié)數(shù)組(第一個參數(shù)buf)中,從offset到指定長度(第二個參數(shù)length)。address指定目的主機的IP和端口號 |
方法:
方法簽名 | 方法說明 |
InetAddress getAddress() | 從接收的數(shù)據(jù)報中,獲取發(fā)送端主機IP地址;或從發(fā)送的數(shù)據(jù)報中,獲取接收端主機IP地址 |
int getPort() | 從接收的數(shù)據(jù)報中,獲取發(fā)送端主機的端口號;或從發(fā)送的數(shù)據(jù)報中,獲取接收端主機端口號 |
byte[] getData() | 獲取數(shù)據(jù)報中的數(shù)據(jù) |
構(gòu)造UDP發(fā)送的數(shù)據(jù)報時,需要傳入SocketAddress,該對象可以使用InetSocketAddress來創(chuàng)建。
構(gòu)造方法:
方法簽名 | 方法說明 |
InetSocketAddress(InetAddress addr, int port) | 創(chuàng)建一個Socket地址,包含IP地址和端口號 |
Echo Server 實現(xiàn)
服務(wù)器核心流程
- 創(chuàng)建?
DatagramSocket
?并綁定到指定端口,開始監(jiān)聽客戶端的請求。 - 循環(huán)接收客戶端發(fā)送的數(shù)據(jù)。
- 將接收到的數(shù)據(jù)原樣發(fā)送回客戶端。
- 重復(fù)步驟 2 和 3,直到服務(wù)器關(guān)閉。
服務(wù)器代碼詳解?
package network;import javax.lang.model.element.NestingKind;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket = null;public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}//通過 start 啟動服務(wù)器的核心流程public void start() throws IOException {System.out.println("服務(wù)器啟動");while (true) {//此處不停的處理客戶端的請求//1.讀取客戶端的請求并解析DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//阻塞并等待客戶端的請求。當數(shù)據(jù)到達時,它將數(shù)據(jù)存儲在?requestPacket?中。socket.receive(requestPacket);//將二進制byte轉(zhuǎn)為字符串,方便輸出String request = new String(requestPacket.getData(),0, requestPacket.getLength());//2.根據(jù)請求計算響應(yīng),由于此處是回顯服務(wù)器,響應(yīng)就是請求.String response = process(request);//3.把響應(yīng)寫回客戶端DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);//4.打印日志System.out.printf("[%s:%d] req=%s,resp=%s\n",requestPacket.getAddress(),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();}
}
Echo Client 實現(xiàn)
客戶端核心流程
- 創(chuàng)建?
DatagramSocket
。 - 從控制臺讀取用戶輸入。
- 將用戶輸入封裝成 UDP 數(shù)據(jù)包并發(fā)送到服務(wù)器。
- 接收服務(wù)器的響應(yīng)并打印到控制臺。
- 重復(fù)步驟 2-4,直到用戶選擇停止。
客戶端代碼詳解?
package network;import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String serverIP;private int serverPort;// 構(gòu)造函數(shù),初始化socket并設(shè)置服務(wù)器的IP和端口public UdpEchoClient(String serverIP,int serverPort) throws SocketException {socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;}public void start() throws IOException {System.out.println("啟動客戶端");Scanner scanner = new Scanner(System.in);while (true) {//1.從控制臺讀取到用戶的輸入System.out.println("-> ");String request = scanner.next();//2.構(gòu)造出一個 UPD 請求,發(fā)送給服務(wù)器// 將用戶輸入轉(zhuǎn)換為字節(jié)數(shù)組,并發(fā)送到服務(wù)器的指定IP和端口DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(this.serverIP),this.serverPort);socket.send(requestPacket);//3.從服務(wù)器讀取到響應(yīng)DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);socket.receive(responsePacket);//響應(yīng)轉(zhuǎn)換為字符串String response = new String(responsePacket.getData(),0,responsePacket.getLength());//4.把響應(yīng)打印到控制臺上System.out.println(response);}}public static void main(String[] args) throws IOException {//創(chuàng)建客戶端示例,綁定本地的9090端口UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);client.start();}
}
運行演示?
1.依次啟動server 和 client:
2.在client中輸入請求內(nèi)容,回車:
?綠色文本為輸入內(nèi)容,白色文本為server響應(yīng).
3.server打印請求和響應(yīng)日志:
????????實現(xiàn)一個基礎(chǔ)的 UDP Echo Server 和 Echo Client,理解 UDP 協(xié)議的工作原理和網(wǎng)絡(luò)通信的基本概念。這種模式不僅適用于學(xué)習(xí)目的,還可以作為構(gòu)建更復(fù)雜網(wǎng)絡(luò)應(yīng)用的基礎(chǔ)。?
希望這篇博客能為你理解網(wǎng)絡(luò)編程提供一些幫助
如有不足之處請多多指出
我是高耳機