UDP 实现的 Echo Server 和 Echo Client 回显程序
欢迎浏览高耳机的博客
希望我们彼此都有更好的收获
感谢三连支持!
在网络编程中,Echo Server 和 Echo Client 回显是一种经典的示例,用于演示基本的网络通信。Echo Server 接收来自客户端的数据,并将相同的数据发送回客户端。这种模式在测试网络连接和理解网络通信原理时非常有用。在这篇文章中,我们将使用 Java 语言来实现基于 UDP 协议的 Echo Server 和 Echo Client。
UDP 协议概述
UDP(User Datagram Protocol)是一种无连接的网络协议,它在 IP 协议的基础上提供一种快速、简单的数据传输服务。与 TCP 协议不同,UDP 不建立连接,不保证数据的可靠传输,因此适用于对实时性要求高、可以容忍一定数据丢失的应用场景,如视频会议、在线游戏等。
API介绍
DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。
构造方法:
方法签名 | 方法说明 |
DatagramSocket() | 创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口(一般用于客户端) |
DatagramSocket(int port) | 创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端) |
方法:
方法签名 | 方法说明 |
void receive(DatagramPacket p) | 从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待) |
void send(DatagramPacket p) | 从此套接字发送数据报包(不会阻塞等待,直接发送) |
void close() | 关闭此数据报套接字 |
DatagramPacket 是UDP Socket发送和接收的数据报。
构造方法:
方法签名 | 方法说明 |
DatagramPacket(byte[] buf, int length) | 构造一个DatagramPacket用来接收数据报,接收的数据保存在字节数组(第一个参数buf)中,接收指定长度(第二个参数length) |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) | 构造一个DatagramPacket用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从offset到指定长度(第二个参数length)。address指定目的主机的IP和端口号 |
方法:
方法签名 | 方法说明 |
InetAddress getAddress() | 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址 |
int getPort() | 从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端口号 |
byte[] getData() | 获取数据报中的数据 |
构造UDP发送的数据报时,需要传入SocketAddress,该对象可以使用InetSocketAddress来创建。
构造方法:
方法签名 | 方法说明 |
InetSocketAddress(InetAddress addr, int port) | 创建一个Socket地址,包含IP地址和端口号 |
Echo Server 实现
服务器核心流程
- 创建
DatagramSocket
并绑定到指定端口,开始监听客户端的请求。 - 循环接收客户端发送的数据。
- 将接收到的数据原样发送回客户端。
- 重复步骤 2 和 3,直到服务器关闭。
服务器代码详解
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 启动服务器的核心流程
public void start() throws IOException {
System.out.println("服务器启动");
while (true) {
//此处不停的处理客户端的请求
//1.读取客户端的请求并解析
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
//阻塞并等待客户端的请求。当数据到达时,它将数据存储在 requestPacket 中。
socket.receive(requestPacket);
//将二进制byte转为字符串,方便输出
String request = new String(requestPacket.getData(),0, requestPacket.getLength());
//2.根据请求计算响应,由于此处是回显服务器,响应就是请求.
String response = process(request);
//3.把响应写回客户端
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 实现
客户端核心流程
- 创建
DatagramSocket
。 - 从控制台读取用户输入。
- 将用户输入封装成 UDP 数据包并发送到服务器。
- 接收服务器的响应并打印到控制台。
- 重复步骤 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;
// 构造函数,初始化socket并设置服务器的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.构造出一个 UPD 请求,发送给服务器
// 将用户输入转换为字节数组,并发送到服务器的指定IP和端口
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),
request.getBytes().length, InetAddress.getByName(this.serverIP),this.serverPort);
socket.send(requestPacket);
//3.从服务器读取到响应
DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
//响应转换为字符串
String response = new String(responsePacket.getData(),0,responsePacket.getLength());
//4.把响应打印到控制台上
System.out.println(response);
}
}
public static void main(String[] args) throws IOException {
//创建客户端示例,绑定本地的9090端口
UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}
运行演示
1.依次启动server 和 client:
2.在client中输入请求内容,回车:
绿色文本为输入内容,白色文本为server响应.
3.server打印请求和响应日志:
实现一个基础的 UDP Echo Server 和 Echo Client,理解 UDP 协议的工作原理和网络通信的基本概念。这种模式不仅适用于学习目的,还可以作为构建更复杂网络应用的基础。
希望这篇博客能为你理解网络编程提供一些帮助
如有不足之处请多多指出
我是高耳机