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);
        }
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

外包干了2个月,技术倒退2年。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;20年通过校招进入深圳某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

maven环境搭建

maven历史版本下载&#xff1a;https://archive.apache.org/dist/maven/ 新建系统变量编辑Path&#xff0c;添加bin目录mvn -v测试查看版本号conf目录下新建repository文件夹&#xff0c;作为本地仓库 settings.xml <?xml version"1.0" encoding"UTF-8&q…

JAVAEE初阶相关内容第十八弹--网络原理之TCP_IP【续集】

写在前 上一篇博客的重点内容主要讲了关于传输层的TCP协议、UDP协议。 点击跳转上一篇博客 重点介绍了协议的特点、协议端格式、需要重点理解并掌握TCP的工作机制&#xff08;十条&#xff09;。 TCP与UDP对比&#xff1f; TCP用于可靠传输的情况&#xff0c;应用于文件传输&am…

【优选算法】202.快乐数

一&#xff0c;题目解析 图形结合&#xff1a; 二&#xff0c;算法原理 快慢双指针 1&#xff0c;定义快慢指针 2&#xff0c;慢指针每次移动一步&#xff0c;快指针一次移动两步 3&#xff0c;判断相遇时的值为1即为快乐数 三&#xff0c;编写代码 class Solution {publ…

Leetcode.2477 到达首都的最少油耗

题目链接 Leetcode.2477 到达首都的最少油耗 rating : 2012 题目描述 给你一棵 n n n 个节点的树&#xff08;一个无向、连通、无环图&#xff09;&#xff0c;每个节点表示一个城市&#xff0c;编号从 0 0 0 到 n − 1 n - 1 n−1 &#xff0c;且恰好有 n − 1 n - 1 n−…

微信小程序pc端样式调试:默认宽高为1024*812,全屏宽高为1920*1032

最近开发调试pc端小程序&#xff0c;想知道默认打开和全屏这两种情况下的小程序宽高&#xff0c;发现了一种方法&#xff1a; 真机运行pc端小程序&#xff0c;点击devTools 在控制台直接打印window对象&#xff0c;可以获取到pc端默认屏幕宽高为1024812&#xff0c;全屏pc端小…

【实用+干货】如何使用Clickhouse搭建百亿级用户画像平台看这一篇就够了

背景 如果你是用户&#xff0c;当你使用抖音、小红书的时候&#xff0c;假如平台能根据你的属性、偏好、行为推荐给你感兴趣的内容&#xff0c;那就能够为你节省大量获取内容的时间。 如果你是商家&#xff0c;当你要进行广告投放的时候&#xff0c;假如平台推送的用户都是你潜…

【无标题】什么是UL9540测试,UL9540:2023版本增加哪些测试项目

什么是UL9540测试&#xff0c;UL9540:2023版本增加哪些测试项目 UL 9540是美国安全实验室&#xff08;Underwriters Laboratories&#xff09;发布的标准&#xff0c;名称为"UL 9540: Energy Storage Systems and Equipment"&#xff0c;翻译为中文为"能量存储…

Vue Computed

小满&#xff0c;我的神&#xff01; 视频链接 // 只读 const plusOne computed(() > count.value 1) // 可读可写 const plusOne computed({get: () > count.value 1,set: (val) > {count.value val - 1} }, { // 用于调试onTrack(e) {debugger},onTrigger(e) …

坚鹏:中国工商银行内蒙古分行数字化转型发展现状与成功案例培训

中国工商银行围绕“数字生态、数字资产、数字技术、数字基建、数字基因”五维布局&#xff0c;深入推进数字化转型&#xff0c;加快形成体系化、生态化实施路径&#xff0c;促进科技与业务加速融合&#xff0c;以“数字工行”建设推动“GBC”&#xff08;政务、企业、个人&…

5.2k Star!一个可视化全球实时天气开源项目!

大家好&#xff0c;本文给大家推荐一款全球实时天气开源项目&#xff1a;Earth。 项目简介 Earth 是一个可视化全球天气实况的项目。该项目以可视化的方式展示了全球的天气情况&#xff0c;提供了风、温度、相对湿度等多种天气数据&#xff0c;以及风、洋流和波浪的动画效果…

openlayers地图使用---跟随地图比例尺动态标绘大小的一种方式

openlayers地图使用—跟随地图比例尺动态标绘大小的一种方式 预期&#xff1a;随着地图比例尺放大缩小&#xff0c;地图上的标绘随着变化尺寸 结果图 页面元素 <script src"https://cdn.bootcdn.net/ajax/libs/openlayers/8.1.0/dist/ol.min.js"></script…

Python标准库:time模块【侯小啾Python基础领航计划 系列(十八)】

Python标准库:time模块【侯小啾Python基础领航计划 系列(十八)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ…

Linux下的java环境搭建

1&#xff0c;安装jdk 上传linux使用的jdk到/opt目录下 解压tar -zxvf文件 配置环境变量 vim /etc/profile 在文件中添加 export JAVA_HOME/opt/jdk8 export PATH$PATH:$JAVA_HOME/bin 使文件生效 source /etc/profile 2,安装tomcat 将tomcat包解压&#xff0c;进入bi…

深度学习在图像识别中的应用

深度学习在图像识别中的应用 摘要&#xff1a;本文介绍了深度学习在图像识别领域的应用&#xff0c;包括卷积神经网络&#xff08;CNN&#xff09;的基本原理、常见模型以及在图像识别中的优势。并通过实验展示了深度学习在图像识别中的实际应用和效果。 一、引言 随着数字化…

新华三数字大赛复赛知识点 VLAN基本技术

VLAN IEEE 802.1Q 交换机端口类型 MVRP协议 VLAN Virtual LAN虚拟局域网。LAN可以是由几台少数家用计算机构成的网络&#xff0c;也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络–也就是广播域。将一个物理的局域网在逻辑上划分成多个广播域…

3、抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;在工厂模式上添加了一个创建不同工厂的抽象接口&#xff08;抽象类或接口实现&#xff09;&#xff0c;可称该接口为作“超级工厂”。在使用过程中&#xff0c;首先通过抽象接口创建出不同的工厂对象&#xff0c;…

SQL Server的安装和首个库的创建

一、熟悉SQL Server的安装环境&#xff1b; 1.安装Microsoft的数据库管理系统SQL Server 2022 先把SQL Server 2022下载好后进行解压后出现以下界面然后点击基本进行安装 然后会出现以下界面&#xff1a; 一步步按照提示往下走即可&#xff0c;把SQL Server 2022安装完成后再…

代码随想录算法训练营 ---第五十五天

今天是 动态规划&#xff1a;编辑距离问题。 第一题&#xff1a; 简介&#xff1a; 动态规划五部曲&#xff1a; 1.确定dp数组的含义 dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c;和以下标j-1为结尾的字符串t&#xff0c;相同子序列的长度为dp[i][j]。 2.确定递推公…

性能测试流程、指标及常见问题!

1.介绍性能测试流程 a.性能需求分析&#xff08;评审&#xff09; 基于接口或者场景&#xff08;全链路&#xff09;的性能测试指标&#xff0c;一般是tps&#xff08;每秒事务数&#xff0c;这里都是通过的事务&#xff09;及art&#xff08;平均响应时间&#xff09; b.了解…