Java网络通信实践:UDP协议下的套接字编程指南

网络通信基础

在网络应用开发中,主要涉及两个关键角色:请求方(客户端)和服务提供方(服务器)。请求方向服务端发起操作指令,服务端接收并处理这些指令后,将处理结果返回给请求方。
开发人员通常关注应用层和传输层的实现。我们编写的程序属于应用层范畴,需要借助传输层提供的接口完成数据传输。Java语言为开发者提供了两套网络通信接口:基于UDP协议的和基于TCP协议的。本文将重点探讨UDP协议下的数据报套接字编程技术。
Socket套接字是操作系统提供的网络通信技术,作为TCP/IP协议网络通信的基础单元。基于Socket的网络应用开发就是我们常说的网络编程。

UDP数据报通信

数据报套接字(DatagramSocket)

DatagramSocket的主要作用是确定通信端点位置,负责数据报的收发操作。
创建方法:
方法名称 | 功能说明
-------|--------
DatagramSocket() | 自动分配可用端口
DatagramSocket(int port) | 手动指定特定端口
数据收发方法:
方法名称 | 功能说明
-------|--------
send(DatagramPacket p) | 发送数据报文
receive(DatagramPacket p) | 接收数据报文(参数会被方法内部修改)
关于输出型参数:
这类参数在方法执行过程中会被修改,且修改结果会反映到方法外部的实际参数上。
资源释放方法:
方法名称 | 功能说明
-------|--------
close() | 释放套接字资源
重要提示:网络编程使用的Socket与文件、内存等资源一样,都需要及时释放。

数据报文(DatagramPacket)

DatagramPacket即传输的数据单元,包含实际传输内容。
创建方法:
Java网络通信实践:UDP协议下的套接字编程指南
字节数组用于存储数据内容(属于输出型参数)
offset参数指定数据起始位置
length参数确定数据长度
address参数包含目标地址信息(SocketAddress包含完整地址,InetAddress仅含IP,port为端口号)
常用方法:
方法名称 | 功能说明 | 返回类型
-------|--------|--------
getAddress() | 获取IP地址 | InetAddress
getPort() | 获取端口号 | int
getSocketAddress() | 获取完整地址 | SocketAddress
getData() | 获取数据内容 | byte[]
getLength() | 获取数据长度 | int

套接字地址(InetSocketAddress)

创建方法:
方法名称 | 功能说明
-------|--------
InetSocketAddress(InetAddress addr, int port) | 创建包含IP和端口的地址对象
实用方法:
方法名称 | 功能说明 | 备注
-------|--------|--------
getByName(String host) | 主机名转IP地址 | 静态方法
该方法作用:
人类可读的IP地址格式(如"xxx.xxx.xxx.xxx")需要转换为机器可识别的二进制格式,此方法完成这一转换。

实现回声服务器

回声服务器的功能是将接收到的数据原样返回。下面演示如何构建这样的服务器。
首先创建服务器类UdpEchoServer,定义核心字段DatagramSocket:

private DatagramSocket socket;
// 指定服务端口
public UdpEchoServer(int port) throws SocketException {
socket = new DatagramSocket(port);
}

固定端口号确保客户端能够准确定位服务位置。

服务启动流程

服务器需要持续运行,使用无限循环处理请求:
创建接收缓冲区:

// 准备接收缓冲区
DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);

接收客户端数据:

// 等待客户端请求
socket.receive(requestPacket);

若无数据到达,程序会在此处阻塞等待。
数据处理逻辑:

// 解析请求内容
String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
// 生成响应内容
String response = process(request);
// 核心业务处理
private String process(String request) {
return request;
}

构建并发送响应:

// 准备响应报文
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
response.getBytes().length, requestPacket.getSocketAddress());
// 发送响应
socket.send(responsePacket);

注意:UDP协议不保存通信对端信息,因此需要从请求报文中获取客户端地址。
记录操作日志:

// 输出处理日志
System.out.printf("[%s : %d] 请求: %s 响应: %sn",
requestPacket.getAddress().toString(),
requestPacket.getPort(),request,response);

完整实现

import java.io.IOException;
import java.net.*;
public class UdpEchoServer {
private DatagramSocket socket;
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] 请求: %s 响应: %sn",
requestPacket.getAddress().toString(),
requestPacket.getPort(),request,response);
}
}
private String process(String request) {
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server = new UdpEchoServer(9090);
server.start();
}
}

客户端实现

客户端需要预先知道服务端地址信息:

private DatagramSocket socket;
private String serverIP;
private int serverPort;

初始化配置:

public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
this.serverPort = serverPort;
this.serverIP = serverIP;
socket = new DatagramSocket(); // 自动分配客户端端口
}

客户端工作流程

接收用户输入并发送请求:

// 准备请求报文
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);

完整实现

import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
private DatagramSocket socket;
private String serverIP;
private int serverPort;
public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
this.serverPort = serverPort;
this.serverIP = serverIP;
socket = new DatagramSocket();
}
public void start() throws IOException {
System.out.println("客户端就绪...");
Scanner scan = new Scanner(System.in);
while(true) {
System.out.println("请输入请求内容:");
String request = scan.nextLine();
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);
}
}
public static void main(String[] args) throws IOException {
UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}

演示效果:
服务端运行效果
客户端运行效果

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/9610.html

(0)
LomuLomu
上一篇 17小时前
下一篇 16小时前

相关推荐

  • Python在多个Excel文件中找出缺失数据行数多的文件

    本文介绍基于Python 语言,针对一个文件夹 下大量的Excel 表格文件,基于其中每一个文件 内、某一列数据 的特征,对其加以筛选,并将符合要求 与不符合要求 的文件分别复制到另外两个新的文件夹 中的方法。 首先,我们来明确一下本文的具体需求。现有一个文件夹,其中有大量的Excel 表格文件(在本文中我们就以csv格式的文件为例);如下图所示。 其中,每…

    2025 年 1 月 12 日
    17500
  • 锚点效应在独立站价格优化中的实践-《认知偏差指南》

    锚点效应在独立站价格优化中的实践-《认知偏差指南》 优化前后的价格呈现对比 原始促销价格展示方式 改进后的价格展示方案 理解锚点效应的本质 人们在做出判断时,往往会过度依赖最初获得的信息(即锚点),即便这些信息与当前决策并无直接关联。在决策过程中,人们习惯性地以这些初始信息为参照,迅速形成判断。 — 《认知偏差指南》 实施优化的心路历程 最初在搭建的几个独…

    20小时前
    1000
  • 深入理解 Java 接口的回调机制

    前言 回调是一种非常重要的编程技术,它广泛应用于事件驱动的编程、异步任务和框架设计中。在 Java 中,回调机制通常通过 接口 来实现。本篇博客将详细解析 Java 接口的回调原理、实现方式,以及实际开发中的应用场景。 泪崩了,期末JAVA编程考了回调,小编不会。 一、什么是回调? 回调(Callback) 是指通过将一个方法作为参数传递给另一个方法,在某些…

    2025 年 1 月 19 日
    15400
  • Java-学生管理系统[初阶]

    让我们来探索如何使用Java语言构建一个基础的“学生信息管理系统”。这个系统将允许我们管理学生的基本信息,包括添加、删除、修改和查询学生数据。接下来,我们将分步骤实现这个系统,并在后续的文章中探讨如何为其添加模拟登录功能。 基础版学生管理系统 在深入代码之前,我们需要掌握以下Java编程基础: Java的输入输出操作 Java的分支与循环结构 Java数组的…

    未分类 2024 年 12 月 27 日
    12100
  • Java 技术全景 —— 运用 Java 实现城市交通大数据可视化分析与智能治理方案(191)

    ✨尊敬的读者朋友们,诚挚欢迎您访问【智汇科技园】!在这个数字化浪潮奔涌的时代,我们致力于打造一个融合创新技术与实践应用的交流平台。本博客将持续为您呈现前沿技术解析与实战案例,期待与您共同探索科技发展的无限可能!✨全网平台(微信公众号/CSDN/抖音/华为/支付宝/微博):智汇科技一、欢迎加入【技术精英圈】快速加入通道1:【智汇技术精英社群(最新)】快速加入通…

    2天前
    2300

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信