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
上一篇 2025 年 5 月 13 日 下午4:11
下一篇 2025 年 5 月 13 日 下午5:12

相关推荐

  • Markdown学习

    Markdown学习 (使用软件Typora) 标题 “#”个数加空格,最多支持到六级标题,其中一级标题是最大的 字体 粗体,两边都加**,然后空格 例如粗体 斜体,两边都加*,然后空格 例如 斜体 (思考?斜体加粗怎么实现呢?——三个星号然后空格就行,例如 斜体加粗 ) 删除线,两边都加~~,然后空格 例如~~删除线~~ 引用 一个>加上一个空格,效果如下…

    2025 年 1 月 13 日
    65200
  • 交易系统:应用层、领域层分层架构设计

    大家好,我是汤师爷~ 线上线下交易系统的应用架构包括终端、应用层、领域层和关联系统。 应用层能力 应用层定义软件的应用功能,负责接收用户请求、协调领域层执行任务并返回结果。主要包括以下模块: 1)C端服务模块 为消费者提供完整的交易链路功能,包括加购、下单、支付、结算、拆单、确认收货和退货退款等。 2)商家后台 为商家提供全面的订单管理功能,包括订单操作、搜…

    2024 年 12 月 28 日
    72200
  • Grok Super开通会员代充完整教程

    国内用户开通 Grok Super 的充值教程,整理 Grok 充值、代充、国内支付、账号 ID 获取和确认充值步骤。

    未分类 2026 年 6 月 15 日
    31200
  • ChatGPT Plus代充流程充值开通教程

    如果没有海外信用卡,ChatGPT Plus 充值会比注册账号更麻烦。 通过卡密充值,可以先用国内支付购买,再用 Session 确认当前 ChatGPT 账号。这样不需要切换共享账号,也能保留自己的使用记录和工作资料。

    未分类 2026 年 6 月 21 日
    24900
  • ChatGPT Plus充值原账号升级指南

    很多做写作训练的人并不是不会注册 ChatGPT,而是卡在 Plus 付款这一步:想让续费也更好管理时,官方订阅就会变得很绕。比较直接的处理方式,是把会员充值到自己的原账号上,先购买卡密,再提交当前账号的 Session,最后核对邮箱和账号信息。这样既不用换共享账号,也能继续保留平时的使用记录。

    未分类 2026 年 8 月 13 日
    13500

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信