【Java】面向UDP接口的网络编程
【Java】面向UDP接口的网络编程
- 一. 基本通信模型
- 二. API
- DatagramSocket
- DatagramPacket
- 三. 回显服务器/客户端示例
- 服务器
- 客户端
- 总结
一. 基本通信模型

- UDP协议是面向数据报的,因此此处要构建数据报(Datagram)在进行发送。
二. API
DatagramSocket
DatagramSocket 是UDP Socket,⽤于发送和接收UDP数据报。
DatagramSocket 构造⽅法:
| ⽅法签名 | ⽅法说明 |
|---|---|
| DatagramSocket() | 创建⼀个UDP数据报套接字的Socket,绑定到本机任意⼀个随机端⼝(⼀般⽤于客⼾端) |
| DatagramSocket(int port) | 创建⼀个UDP数据报套接字的Socket,绑定到本机指定的端⼝(⼀般⽤于服务端) |
DatagramSocket ⽅法:
| ⽅法签名 | ⽅法说明 |
|---|---|
| void receive(DatagramPacket p) | 从此套接字接收数据报(如果没有接收到数据报,该⽅法会阻塞等待) |
| void send(DatagramPacket p) | 从此套接字发送数据报包(不会阻塞等待,直接发送) |
| void close() | 关闭此数据报套接字 |
DatagramPacket
DatagramPacket是UDP Socket发送和接收的数据报。
DatagramPacket 构造⽅法:
| ⽅法签名 | ⽅法说明 |
|---|---|
| DatagramPacket(byte[] buf, int length) | 构造 DatagramPacket用于接收长度为 length数据包。 |
| DatagramPacket(byte[] buf,int length, SocketAddress address) | 构造数据报包,用于将长度为 length的数据包发送到指定主机上的指定端口号。address指定⽬的主机的IP和端⼝号 |
| DatagramPacket(byte[] buf, int length, InetAddress address, int port) | 构造一个数据报包,用于将长度为 length的数据包发送到指定主机上的指定端口号。 |
DatagramPacket ⽅法:
| ⽅法签名 | ⽅法说明 |
|---|---|
| InetAddress.getAddress() | 从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址 |
| int getPort() | 从接收的数据报中,获取发送端主机的端⼝号;或从发送的数据报中,获取接收端主机端⼝号 |
| byte[] getData() | 获取数据报中的数据 |
三. 回显服务器/客户端示例
服务器
服务器端往往需要经历三个步骤:
- 读取客户端发来的请求并解析
//没有请求在receive处阻塞等待DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//读取到的字节数组转成String,方便后的逻续辑处理//getLength()得到的是有效长度String request=new String(requestPacket.getData(),0,requestPacket.getLength());
此处构造一个DatagramPacket用来接收请求,如果没有请求,则进入阻塞等待状态。
- 根据请求计算响应
String response=process(request);
根据不同的业务场景,来设计不同的计算过程,可以将计算过程单独写一个方法:
//根据不同的需求,设计不同的计算处理
//此处只是将请求返回,来观察通信过程
public String process(String request) {return request;
}
- 把响应返回给客户端
//构造一个 DatagramPacket 作为响应对象
DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
socket.send(responsePacket);
- [可选]打印日志
System.out.printf("[%s:%d] req:%s, rsep:%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);
完整代码:
import java.io.IOException;
import java.net.*;public class UdpEchoServer {//socket为网卡private DatagramSocket socket=null;public UdpEchoServer(int port) throws SocketException {socket=new DatagramSocket(port);}//服务器启动逻辑public void start() throws IOException {System.out.println("server has been started!");while(true){//循环一次,请求一个请求-响应过程//1.读取请求并解析//没有请求在receive处阻塞等待DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//读取到的字节数组转成String,方便后的逻续辑处理//getLength()得到的是有效长度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, rsep:%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(10100);server.start();}
}
- 对于服务器端,往往会指定端口,便于客户端的访问。
客户端
客户端要从控制台读取客户的请求,因此需要经历四个步骤:
- 从控制台读取要发送的请求
Scanner scanner=new Scanner(System.in);
System.out.print(">");
//1.从控制台读取要发送的请求
if (!scanner.hasNext()) {break;}
String request=scanner.next();
- 构造数据报并发送
DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP),serverPort);
socket.send(requestPacket);
此处的serverIP和serverPort在构造方法处得到,这也是为什么我们要给服务器写一个指定的端口。
- 读取服务器的响应
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=null;private String serverIP;private int serverPort;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("client has been started!");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 {//环回IPUdpEchoClient client=new UdpEchoClient("127.0.0.1",10100);client.start();}
}
- 客户端是不需要指定端口的,是因为:指定的端口有可能被占用,且客户端往往由客户使用(不一定懂代码)。
- "127.0.0.1"是回显地址,即本机地址。
总结
构造DatagramPacket的三种方法的使用场景:
| ⽅法签名 | ⽅法说明 |
|---|---|
| DatagramPacket(byte[] buf, int length) | 构造 DatagramPacket用于接收长度为 length数据包。 |
| DatagramPacket(byte[] buf,int length, SocketAddress address) | 构造数据报包,用于将长度为 length的数据包发送到指定主机上的指定端口号。address指定⽬的主机的IP和端⼝号 |
| DatagramPacket(byte[] buf, int length, InetAddress address, int port) | 构造一个数据报包,用于将长度为 length的数据包发送到指定主机上的指定端口号。 |
- 第一种常用于服务器接收请求/客户端接收响应
- 第二种常用于服务器构造响应的数据报(由于接收了客户端的请求,可以读取到客户端的IP和端口号)
- 第三种常用于客户端构造请求的数据报(需要自行输入服务器的IP和端口号)
运行时,要先运行服务器,再运行客户端:

相关文章:
【Java】面向UDP接口的网络编程
【Java】面向UDP接口的网络编程 一. 基本通信模型二. APIDatagramSocketDatagramPacket 三. 回显服务器/客户端示例服务器客户端总结 一. 基本通信模型 UDP协议是面向数据报的,因此此处要构建数据报(Datagram)在进行发送。 二. API DatagramSocket DatagramSocke…...
SRS服务器搭建
1、配置 listen 1935; max_connections 1000; #srs_log_tank file; #srs_log_file ./objs/srs.log; daemon on; http_api { enabled on; listen 1985; } http_server { enabled on; listen 808…...
iMazing只能苹果电脑吗 Win和Mac上的iMazing功能有区别吗
在当今数字时代,管理和备份手机数据变得越来越重要。无论是转移照片、备份短信,还是管理应用程序,一个强大的工具可以大大简化这些操作。iMazing作为一款备受好评的iOS设备管理软件,已经成为许多用户的选择。但是,许多…...
ChatGPT可以分析股票吗?
结合国庆前大A股市的小波牛市以及今天的股市表现,我从多个角度为你提供一些分析和建议: 一、国庆前的小波牛市分析 国庆前,大A股市出现了一波小幅上涨,市场呈现出一些积极的信号: 政策面利好:政府出台了…...
Dockerfile搭建镜像
Dockerfile搭建镜像的优势与区别 引言 在现代软件开发与运维中,容器化技术日益普及,而Docker作为最流行的容器化平台之一,通过Dockerfile提供了一种灵活、自动化的方式来构建Docker镜像。Dockerfile使得镜像的构建过程可重复、可版本化&…...
Kubernetes-Kind篇-01-kind搭建测试集群
1、Kind 介绍 官方文档地址:https://kind.sigs.k8s.io/ github仓库地址:https://github.com/kubernetes-sigs/kind 国内镜像仓库地址:https://gitcode.com/gh_mirrors/ki/kind/overview kind 是一种使用 Docker 容器 nodes 运行本地 Kubern…...
在UniApp中高效处理大量文件请求的策略
在开发跨平台应用时,尤其是在使用UniApp这样的框架时,我们可能会遇到需要同时请求多个文件的情况。然而,不加节制地同时发起大量请求可能会带来严重的性能问题,如界面卡顿、内存溢出、网络带宽饱和等。本文将探讨如何在UniApp中高…...
docker compose入门4—常用命令
在使用 Docker Compose 管理多容器应用时,常见的命令帮助我们高效地管理容器的生命周期、服务、日志等。以下是一些常用的 Docker Compose 命令及其详细讲解: 1. docker-compose up 这个命令用于启动定义在 docker-compose.yml 文件中的服务。 用法&am…...
wps文本框文字居中对齐
直接点对齐里的水平居中,垂直居中是将文本框水平垂直居中,文字不会居中 将文本框里的文字居中: 垂直居中: 水平居中:...
注册信息页面
知识点: !+Enter 直接生成前端基本框架 1.<h1></h1> (2,3,4,5) 表示各级标题 2.<form></form> 表单建立 3.<input type" "></input> 表格(表单嵌套表格) type属…...
详解Java中的BIO、NIO、AIO
1、 详解Java中的BIO、AIO、NIO 1.1、引言 IO流是Java中比较难理解的一个知识点,但是IO流在实际的开发场景中经常会使用到,比如Dubbo底层就是NIO进行通讯。本文将介绍Java发展过程中出现的三种IO:BIO、NIO以及AIO,重点介绍NIO。…...
CAN和CANFD如何转换和通信
随着科技的发展,汽车电子和工业领域中CAN通信需要承载数据量也越来越大,传统CAN通信有了向CANFD通信过渡的倾向。在实现过渡的过程中可能会出现自己设备是CAN通信,客户设备是CANFD通信的情况,或者自己设备是CANFD通信,…...
QDateTimeEdit Class
Header:#include qmake:QT += widgets Inherits:QAbstractSpinBox Inherited By:QDateEdit and QTimeEdit Public Types enum Section {NoSection, AmPmSection, MSecSection, SecondSection, MinuteSection, …, YearSection } flags SectionsProperties calendarPopu…...
Windows环境安装CentOS7
【注意】安装CentOS需要先安装Vmware虚拟机 【下载前准备】 一、下载CentOS 7镜像文件阿里云镜像开源,点击跳转 二、安装VMware(17): a. 官网,点击跳转 b. 许可证:JU090-6039P-08409-8J0QH-2YR7F 安装V…...
用docker启动mysql步骤
以下是在 Docker 中启动 MySQL 的详细步骤: **一、拉取 MySQL 镜像 ** 1. 打开终端,确保 Docker 服务正在运行。可以使用以下命令检查 Docker 服务状态: sudo systemctl status docker 2. 使用以下命令拉取 MySQL 官方镜像: d…...
[Linux] Linux 初识进程地址空间 (进程地址空间第一弹)
标题:[Linux] Linux初识进程地址空间 个人主页水墨不写bug (图片来源于AI) 目录 一、什么是进程地址空间 二、为什么父子进程相同地址的变量的值不同 三、初识虚拟地址、页表 一、什么是进程地址空间 其实,在很久之前…...
力扣21~25题
21题(简单): 分析: 按要求照做就好了,这种链表基本操作适合用c写,python用起来真的很奇怪 python代码: # Definition for singly-linked list. # class ListNode: # def __init__(self, v…...
04. prometheus 监控 Windows 服务器
prometheus 监控 Windows 服务器 1. 下载安装 Windows_exporter 安装包下载:https://github.com/prometheus-community/windows_exporter/releases 下载 msi 版本,上传至要监控的 Windows 服务器,双击安装即可,exporter 会自动…...
【机器学习】——决策树以及随机森林
文章目录 1. 决策树的基本概念与结构1.1 决策树的构建过程 2. 决策树的划分标准2.1 信息增益(Information Gain)2.2 信息增益比(Information Gain Ratio)2.3 基尼指数(Gini Index)2.4 均方误差(…...
怎么选择合适的数据恢复软件?适用于 Windows 的数据恢复软件对比
针对 Windows 的领先数据恢复软件的全面回顾: 丢失重要数据对任何 Windows 用户来说都是一场噩梦。从意外删除到系统崩溃,数据丢失是一个非常普遍的问题。值得庆幸的是,有强大的数据恢复工具可以帮助找回丢失的文件。这篇评论深入探讨了适用于…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...
CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...
【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...
