UDP数据报套接字

文章目录

    • DatagramSocket API
    • DatagramPacket API
    • 示例一: 请求响应
      • UDP服务端
      • UDP客户端

DatagramSocket API

Socket是操作系统中的一个概念,本质上是一种特殊的文件,Socket就属于把“网卡”这个设备给抽象成了文件。往 Socket 文件中写数据,就相当于通过网卡发数据,从 Socket 文件中读数据,就相当于通过网卡接收数据。而在Java中,就使用 DatagramSocket 这个类来表示系统内部的 Socket 文件。

DatagramSocket 构造方法

方法方法说明
DatagramSocket()创建一个UDP数据报的Socket,绑定到本机任意一个随机端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报的Socket,绑定到本机指定的端口(一般用于服务端)

DatagramSocket 方法:

方法方法说明
void receive(DatagramPacket p)使用DatagramPacket这个类来表示一个UDP数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacket p)从此套接字中发送数据报(不会阻塞等待,直接发送)
void close()关闭数据报套接字

DatagramPacket API

DatagramPacket 构造方法:

方法方法说明
DatagramPacket(byte[] buf, int length)构造一个DatagramPacket 用来接收数据报,接收的数据保存在字节数组中,指定接收长度(第二个参数length)
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)构造一个DatagramPacket 用来发送数据报,发送的数据为字节数组(第一个参数buf)中,从0到指定长度(第二个参数 length),address指定目的主机的IP和端口号

DatagramPacket 方法:

方法方法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int port()从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主句端口号
byte[] getData()获取数据报中的数据

示例一: 请求响应

任务需求:

1.在客户端这边,从键盘上输入一个路径

2.发送请求,将这个路径构造成数据报发送给服务器

3.服务器接收到请求并计算响应:根据该请求数据,如果是一目录,列出目录中所包含的所有文件及文件夹,如果是一个普通文件,列出文件所在目录中的所有文件及文件夹

4.服务端返回响应:遍历子文件和子文件夹,每个文件名一行,作为响应的数据报返回给客户端

5.客户端接收响应:打印出所有的文件及文件夹

注意:为了解决空字符或读取请求时读取的字符串长度不够,造成数据丢失的情况,这里约定,客户端和服务端发送的数据都已 ‘/3’ 进行结尾,读取到 ‘/3’ 就表示请求或响应都全部读取完成

UDP服务端

public class UdpEchoServer {//1.创建一个DatagramSocket,用于后续接收和发送UDP数据报private static DatagramSocket socket;private static DatagramPacket requestPacket;public UdpEchoServer(int port) throws SocketException {//在服务器这边使用Socket,一般要显示的指定端口号//在客户端,不需要显示的指定端口号,系统会自动分配一个端口号socket = new DatagramSocket(port);}public static void start() throws IOException {while(true) {//2.创建数据报,用于接收客户端发来的数据报byte[] dataRequest = new byte[4024];requestPacket = new DatagramPacket(dataRequest, dataRequest.length);System.out.println("----------------------------------------");System.out.println("等待服务端接收数据");//3.等待客户端发来的数据报,在服务端收到数据报之前,receive()方法会一直阻塞等待,直到收到数据报后,// DatagramPacket对象中,包含客户端发来的数据,客户端IP地址和端口号socket.receive(requestPacket);System.out.println("客户端IP:" + requestPacket.getAddress().getHostAddress());System.out.println("客户端端口号:" + requestPacket.getPort());//7. 根据请求,计算响应for(int i = 0; i < dataRequest.length; i++) {byte b = dataRequest[i];if(b == '\3') {//7.1 读取请求:读取到约定好的结束符'\3',取结束符前的所有内容String request = new String(dataRequest, 0 , i);System.out.println("请求的路径:" + request);//7.2 根据请求计算响应File requestFile = new File(request);File[] children = null;//7.3 判断该路径是否存在if(requestFile.exists()) {if(!requestFile.isDirectory()) {//表示该对象是一个普通文件//获取上级目录路径String parent = requestFile.getParent();requestFile = new File(parent);}children = requestFile.listFiles();}else {String res = "该路径错误!!!" +'\n' + '\3';sendEcho(res);break;}//7.4 构造响应内容,将每个子文件作为一行StringBuilder response = new StringBuilder();for(File child : children) {response.append(child.getName() + '\n');}//7.5 读取完之后,加上约定的结束符response.append('\3');//7.6 发送返回的响应数据sendEcho(response.toString());break;}}}}public static void sendEcho(String response) throws IOException {//构造响应数据报byte[] responseData = response.getBytes(StandardCharsets.UTF_8);DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length, requestPacket.getSocketAddress());//发送返回的响应数据报socket.send(responsePacket);System.out.println("发送完成");}public static void main(String[] args) {try {UdpEchoServer echoServer = new UdpEchoServer(8888);} catch (SocketException e) {throw new RuntimeException(e);}try {UdpEchoServer.start();} catch (IOException e) {throw new RuntimeException(e);}}
}

UDP客户端

public class UdpEchoClient {//4.创建客服端Socket//4.1指定服务端端地址和端口号private static final SocketAddress ADDRESS = new InetSocketAddress("127.0.0.1", 8888);private static DatagramSocket socket;public UdpEchoClient() {//客户端不需要指定端口号try {socket = new DatagramSocket();} catch (SocketException e) {throw new RuntimeException(e);}}public static void start() throws IOException {Scanner in = new Scanner(System.in);while(true) {//5.构建数据报System.out.println("请输入要展开的目录");//5.1 为了接收端能获取到有效的内容,以\3作为结束符;String request = in.nextLine() + '\3';//5.2 将要发送的数据转换成字节,并指定字符集byte[] requestData = request.getBytes(StandardCharsets.UTF_8);//5.3 组装好的数据包中包含了数据,及发送服务端的信息(IP地址、端口号)DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, ADDRESS);//6.发送数据报socket.send(requestPacket);System.out.println("--------------------------------");//8.接收服务端响应的数据报,打印出响应内容//8.1 使用字节数组接收响应数据byte[] responseData = new byte[4090];//8.2 构建响应数据报DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length);//8.3 接收响应socket.receive(responsePacket);//8.4 打印出响应内容System.out.println("该目录下的文件列表为:");//因为,响应中的每个文件都是以回车结尾的,next用于定义每个文件起始位置,int next = 0;for(int i = 0; i < responseData.length; i++) {byte b = responseData[i];if(b == '\3') {//表示响应读取完成break;}if(b == '\n') {//遇见回车键表示读取到了一个文件名//构建字符串文件名String print = new String(responseData, next, i - next);System.out.println(print);//下次解析从换行后的索引开始next = i + 1;}}}}public static void main(String[] args) {UdpEchoClient echoClient = new UdpEchoClient();try {UdpEchoClient.start();} catch (IOException e) {throw new RuntimeException(e);}}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/200199.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入探讨Guava的缓存机制

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天咱们聊聊Google Guava的缓存机制。缓存在现代编程中的作用非常大&#xff0c;它能提高应用性能&#xff0c;减少数据库压力&#xff0c;简直就是性能优化的利器。而Guava提供的缓存功能&#xff0c;不仅强大…

iptables入门

今天我的工作遇到了巡检网络配置的任务&#xff0c;这次巡检的主机都是运行十多年的机器&#xff0c;并不是新的firewalld&#xff0c;基本都是iptables&#xff0c;上学的时候以为这些都没人用&#xff0c;所以没有认真学习&#xff0c;现在需要用到了&#xff0c;所以写一篇文…

PostGIS学习教程九:空间连接

PostGIS学习教程九&#xff1a;空间连接 空间连接&#xff08;spatial joins&#xff09;是空间数据库的主要组成部分&#xff0c;它们允许你使用空间关系作为连接键&#xff08;join key&#xff09;来连接来自不同数据表的信息。我们认为“标准GIS分析”的大部分内容可以表示…

17.认识下Docker之docker的核心原理(2)

1.容器-我的小世界 不知道大家看没看过小说《完美时间》&#xff0c;里面石昊经常进入一个小世界在里面与世隔绝的修炼或者战斗&#xff0c;总之就是在一个完全封闭的空间里做他想做的事情而与外界隔离&#xff0c;不受侵扰。通过前面的分析我们知道&#xff0c;Namepace让应用…

SringBoot的启动原理,保姆级带你认识,让面试管对你刮目相看

SringBoot的启动原理&#xff0c;保姆级带你认识&#xff0c;让面试管对你刮目相看 一&#xff0c;介绍 graph TD; A[启动类] --> B[SpringApplication.run()] B --> C[创建SpringApplication实例] C --> D[初始化应用上下文] D --> E[加载应用配置] E --> F[…

树_二叉搜索树累加求和

//给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值等于原树中大于或等于 // node.val 的值之和。 // // 提醒一下&#xff0c;二叉搜索树满足下列约束…

【Vulnhub 靶场】【hacksudo: FOG】【简单 - 中等】【20210514】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/hacksudo-fog,697/ 靶场下载&#xff1a;https://download.vulnhub.com/hacksudo/hacksudo-FOG.zip 靶场难度&#xff1a;简单 - 中等 发布日期&#xff1a;2021年05月14日 文件大小&#xff1a;1.3 GB 靶场作…

解决 vite 中 import.meta.globEager is not function 的问题

本人正在重构两年前搭建到一半的博客网站&#xff0c;相关依赖都很陈旧&#xff0c;用到了 npm-check-updates 检测项目可升级依赖&#xff1a; 升级完成后解决完依赖发现控制台报错 import.meta.globEager is not function解决方案&#xff1a; vite版本降至4.3.0 亲测有效&…

忽略python运行出现的大量警告

添加以下代码即可 import warnings warnings.filterwarnings(ignore)

App内存优化

一、内存优化介绍 1.背景介绍 内存是大问题但缺乏关注压实骆驼的最后一个稻草&#xff08;堆栈溢出&#xff09; 2.内存问题 内存抖动&#xff1a;锯齿状、GC导致卡顿内存泄露&#xff1a;可用内存减少、频繁GC内存溢出&#xff1a;OOM&#xff0c;程序异常 二、优化工具选…

FreeRTOS简介

FreeRTOS简介 文章目录 FreeRTOS简介前言一、什么是FreeRTOS&#xff1f;二、FreeRTOS的特点三、FreeRTOS的版本和参考资料1、FreeRTOS版本2、FreeRTOS源码获取3、FreeRTOS参考资料 四、FreeRTOS源码简介 前言 FreeRTOS是一个可以基于ROM运行的、可裁剪的、抢占式、实时多任务…

Photoshop最新版PS2024安装使用 Ver25.0.0

Photoshop&#xff0c;这个是长红了几十年的软件&#xff0c;我大概从它的3.0版本开始用&#xff0c;目前已迭代到25.0&#xff0c;但一直还在用CS4/11.0版本&#xff0c;一直秉持着够用即可的原则&#xff0c;因为不是专业的平面设计人员&#xff0c;能够简单PP图片就行。&…

C++智能指针及简单实现

C智能指针 堆内存、栈内存与静态内存静态内存栈内存堆内存 动态内存管理new、delete运算符智能指针实现智能指针 shared_ptr智能指针的线程安全问题解决 unique_ptrweak_ptr循环引用 思维导图本模块思路 动态内存管理 - cppreference.com 堆内存、栈内存与静态内存 静态内存 …

视觉测量基础

1. 相机模型 1.1 坐标系转换原理 世界坐标系(world Coords):点在真实世界中的位置&#xff0c;描述相机位置。 相机坐标系(Cameras Coords):以相机光学系统中心&#xff08;镜头中心&#xff09;为原点&#xff0c;建立相机坐标系。 图像物理坐标系(Film Coords):经过小孔成…

微服务实战系列之J2Cache

前言 经过近几天陆续发布Cache系列博文&#xff0c;博主已对业界主流的缓存工具进行了基本介绍&#xff0c;当然也提到了一些基本技巧。相信各位盆友看见这么多Cache工具后&#xff0c;在选型上一定存在某些偏爱: A同学说&#xff1a;不管业务千变万化&#xff0c;我对Redis的…

企业如何制定精准营销策略?

在当今的数字化时代&#xff0c;位置数据已经成为企业营销策略中不可或缺的一部分。通过收集和分析客户的位置数据&#xff0c;企业可以更好地了解客户的行为和需求&#xff0c;制定更精准的营销策略&#xff0c;从而提高营销效率。 首先&#xff0c;利用IP地址位置数据可以帮助…

手搓图片滑动验证码_JavaScript进阶

手搓图片滑动验证码 背景代码效果图展示网站 背景 在做前端项目开发的时候&#xff0c;少不了登录注册部分&#xff0c;既然有登录注册就少不了机器人验证&#xff0c;验证的方法有很多种&#xff0c;比如短信验证码、邮箱验证码、图片滑动、图片验证码等。 由于鄙人在开发中…

9个Logo素材超多的Logo网站!

Logo 虽然看起来很简单&#xff0c;但是设计过程中的每一个细节都很精致。因为 Logo 作为品牌的象征&#xff0c;应该一目了然地传达给人们品牌的理念和形象。本文给大家整理了 7 个 Logo 素材网站和 2 个 Logo 在线制作网站。可以收集很多关 Logo 设计的内容和技巧&#xff01…

吉他初学者学习网站搭建系列(5)——如何做一个在线节拍器

文章目录 背景实现TransportLoop代码 在线尝试 背景 我们看吉他谱时&#xff0c;经常看到拍号&#xff0c;例如6/8。它的含义是一拍是一个八分音符&#xff0c;一小节有六拍。四分音符的时长是一秒&#xff0c;即60拍/分钟。基于这样的背景知识&#xff0c;我们就可以根据一些…

supervisor管理python进程

前言 平时开发调试中使用conda环境&#xff0c;项目比较多环境多&#xff0c;而且命令繁杂&#xff0c;每一次启动项目都可能会因为忘记启动方式而频繁报错。现在可以通过supervisor来管理&#xff0c;只需要配置几个文件&#xff0c;就可以轻松通过简单一致的命令启动工程&…