UDP数据报套接字编程

news2024/9/24 17:20:56

DatagramSocket API

DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。

DatagramSocket 构造方法:

 

DatagramSocket 方法:


 

DatagramPacket API

DatagramPacket是UDP Socket发送和接收的数据报。
 

DatagramPacket 构造方法:
 

DatagramPacket 方法:


 

 构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创
建。

InetSocketAddress API

InetSocketAddress ( SocketAddress 的子类 )构造方法:
 

示例一:一发一收(无响应)

以下为一个客户端一次数据发送,和服务端多次数据接收(一次发送一次接收,可以接收多次),即只有客户端请求,但没有服务端响应的示例:

UDP客户端

package net1;

import java.io.IOException;
import java.net.*;

public class UdpClient {
    // 服务端socket地址,包含域名或IP,及端口号
    private static final SocketAddress address = new InetSocketAddress("127.0.0.1", 8888);

    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();
        byte[] bytes = "hello i am client".getBytes();
        DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address);
        socket.send(packet);
    }
}



 UDP服务端

package net1;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpServer {
    private static final int port = 8888;

    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(port);

        while (true) {
            byte[] bytes = new byte[1024];
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
            System.out.println("-------------------------------------------");
            System.out.println("等待接收udp数据报...");
            socket.receive(packet);
            System.out.println("客户端ip: " + packet.getAddress().getHostAddress());
            System.out.println("客户端port: " + packet.getPort());
            System.out.println("客户端发送的数据为: " + new String(packet.getData()).substring(0,17));
        }
    }
}

从以上可以看出,发送的UDP数据报(假设发送的数据字节数组长度为M),在接收到以后(假设接收的数据字节数组长度为N):
1. 如果N>M,则接收的byte[]字节数组中会有很多初始化byte[]的初始值0,转换为字符串就是空白
字符;
2. 如果N<M,则会发生数据部分丢失(可以自己尝试,把接收的字节数组长度指定为比发送的字节数组长度更短)。
要解决以上问题,就需要发送端和接收端双方约定好一致的协议,如规定好结束的标识或整个数据的长度。

示例二:请求响应

以下是对应请求和响应的改造:构造一个展示服务端本地某个目录(BASE_PATH)的下一级子文件列表的服务.

  1. 客户端先接收键盘输入,表示要展示的相对路径(相对BASE_PATH的路径)
  2. 发送请求:将该相对路径作为数据报发送到服务端
  3. 服务端接收并处理请求:根据该请求数据,作为本地目录的路径,列出下一级子文件及子文件夹
  4. 服务端返回响应:遍历子文件和子文件夹,每个文件名一行,作为响应的数据报,返回给客户端
  5. 客户端接收响应:简单的打印输出所有的响应内容,即文件列表。
     

为了解决空字符或长度不足数据丢失的问题,客户端服务端约定好统一的协议:这里简单的设计为
ASCII结束字符 \3 表示报文结束。

 

UDP服务端

package net1;

import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UdpEchoServer {
    private static final int port = 8888;
    private static final String base_path = "";

    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(port);
        while (true) {
            byte[] requestData = new byte[1024];
            DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
            System.out.println("--------------------------------------");
            System.out.println("等待接收udp数据报");
            socket.receive(requestPacket);
            System.out.println("客户端ip: " + requestPacket.getAddress().getHostAddress());
            System.out.println("客户端port :" + requestPacket.getPort());

            for (int i = 0; i < requestData.length; i++) {
                byte b = requestData[i];
                if (b == '\3') {
                    String request = new String(requestData, 0, i);
                    System.out.println("客户端请求的文件列表路径为:" + base_path + request);
                    File dir = new File(base_path + request);
                    File[] files = dir.listFiles();
                    StringBuilder response = new StringBuilder();
                    if (files != null) {
                        for (File f : files) {
                            response.append(f.getName() + "\n");
                        }
                    }
                    response.append("\3");
                    byte[] responseData = response.toString().getBytes(StandardCharsets.UTF_8);
                    DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length, requestPacket.getSocketAddress());
                    socket.send(responsePacket);
                    break;
                }
            }
        }
    }
}


 

UDP客户端

package net1;

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class UdpEchoClient {
    private static final SocketAddress address = new InetSocketAddress("127.0.0.1", 8888);

    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("--------------------------------");
            System.out.println("请输入要展示的目录");
            String request = scanner.next() + "\3";
            byte[] requestData = request.getBytes(StandardCharsets.UTF_8);
            DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, address);
            socket.send(requestPacket);

            byte[] responseData = new byte[1024];
            DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length);
            socket.receive(responsePacket);
            System.out.println("该目录下的文件列表为:");

            int next = 0;
            for (int i = 0; i < responseData.length; i++) {
                byte b = responseData[i];
                if (b == '\3') {
                    break;
                }
                if (b == '\n') {
                    String fileName = new String(responseData, next, i - next);
                    System.out.println(fileName);
                    next = i + 1;
                }
            }
        }
    }
}


 

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

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

相关文章

本地生成动漫风格 AI 绘画 图像|Stable Diffusion WebUI 的安装和局域网部署教程

Stable Diffusion WebUI 的安装和部署教程1. 简介2. 安装环境2.1 Windows2.2 Linux3. 运行4. 模型下载链接5. 局域网部署5.1 Windows5.2 Linux6. 其他资源1. 简介 先放一张WebUI的图片生成效果图&#xff0c;以给大家学习的动力 &#xff1a;&#xff09; 怎么样&#xff0c;…

浅析SAS协议(1):基本介绍

文章目录概述SAS协议发展历程SAS技术特性SAS设备拓扑SAS phySAS地址SAS设备类型SAS协议分层参考链接概述 SAS&#xff0c;全称Serial Attached SCSI&#xff0c;即串行连结SCSI&#xff0c;是一种采用了串行总线的高速互连技术。通过物理上使用串行总线连结&#xff0c;在链路…

用一行Python代码,为图片上水印版权!

今天一个朋友跟我吐槽&#xff1a;前段时间&#xff0c;我辛辛苦苦整理的一份XX攻略&#xff0c;分享给自己的一些朋友&#xff0c;结果今天看到有人堂而皇之地拿着这份攻略图片去引流&#xff0c;并声称是自己整理的&#xff0c;真是岂有此理&#xff01;他自己总结吃一堑长一…

超低成本DDoS攻击来袭,看WAF如何绝地防护

一、DDoS攻击&#xff0c;不止于网络传输层 网络世界里为人们所熟知的DDoS攻击&#xff0c;多数是通过对带宽或网络计算资源的持续、大量消耗&#xff0c;最终导致目标网络与业务的瘫痪&#xff1b;这类DDOS攻击&#xff0c; 工作在OSI模型的网络层与传输层&#xff0c;利用协…

【MyBatis】源码学习 03 - 类型处理器 TypeHandler

文章目录前言参考目录学习笔记1、type 包中类的归类总结2、类型处理器2.1、TypeReference 类3、类型注册表3.1、TypeHandlerRegistry#getTypeHandler前言 本文内容对应的是书本第 8 章的内容&#xff0c;主要是关于类型处理器 TypeHandler 的学习。 这一章节的学习有些地方理…

Java爬虫——WebMagic案例

抓取51Job的招聘信息一&#xff0c; Scheduler组件在解析页面的时候&#xff0c;很可能会解析出相同的url地址(例如商品标题和商品图片超链接&#xff0c;而且url一样)&#xff0c;如果不进行处理&#xff0c;同样的url会解析处理多次&#xff0c;浪费资源。所以我们需要有一个…

【Unity3d】Unity与Android之间通信

在unity开发或者sdk开发经常遇到unity与移动端原生层之间进行通信&#xff0c;这里把它们之间通信做一个整理。 关于Unity与iOS之间通信&#xff0c;参考【Unity3d】Unity与iOS之间通信 Unity(c#)调用Android (一)、编写Java代码 实际上&#xff0c;任何已经存在的Java代码…

【webpack5】一些常见优化配置及原理介绍(二)

这里写目录标题介绍sourcemap定位报错热模块替换&#xff08;或热替换&#xff0c;HMR&#xff09;oneOf精准解析指定或排除编译开启缓存多进程打包移除未引用代码配置babel&#xff0c;减小代码体积代码分割&#xff08;Code Split&#xff09;介绍预获取/预加载(prefetch/pre…

HydroD 实用教程(四)水动力模型

目 录一、前言二、Hydro Properties2.1 Compartment Properties2.2 Rudder and Thruster2.3 Wind Properties三、Hydro Structure3.1 Load Cross Sections四、Loading Conditions4.1 Mass Model4.2 Second Order Surface Model4.3 Wadam Offbody Points4.4 Additional Matrices…

Redis的常见操作和Session的持久化

安装Redis使用yum命令&#xff0c;直接将redis安装到linux服务器&#xff1a;yum -y install redis启动redis使用以下命令&#xff0c;以后台运行方式启动redis&#xff1a;redis -server /etc/redis.conf &操作redis使用以下命令启动redis客户端&#xff1a;redis-cli设置…

vscode连接服务器(腾讯云)

文章目录1. vscode远程总是报错2. vscode能连上腾讯云但密码不对或者登录后不能打开文件或文件夹1. vscode远程总是报错 报错如图所示 Could not establish connection to *** 过程试图写入的管道不存在。 在百度、csdn找了好久都是说删掉.ssh文件下的某个文件但我压根没有&a…

使用 nutjs实现前端RPA需求

nutjs 相关概念 nut.js 是 Node.js 的桌面自动化框架&#xff0c;我们可以使用 js / ts 来控制鼠标和键盘&#xff0c;来模拟人的操作完成一系列动作。它主要分为以下三块内容&#xff1a; KeyboardMouseScreen Keyboard 常用 API type: 它允许我们输入 键 或 字符串&#…

linux013之文件和目录的权限管理

用户、组、文件目录的关系&#xff1a; 简介&#xff1a;用户和组关联&#xff0c;组合文件目录关联&#xff0c;这样就实现了用户对文件的权限管理。首先来看一下&#xff0c;一个文件或目录的权限是怎么查看的&#xff0c;ls -l&#xff0c; 如下&#xff0c;这个信息怎么看呢…

71. Python 库与模块

71. 库与模块 文章目录71. 库与模块1. Python 就是一个解释器2. 什么模块3. 什么是包5. 什么是库6. 形象理解模块与库7. 库的分类1. 标准库2. 第三方库8. 总结1. Python 就是一个解释器 我们把程序员编写的代码形象理解为写了一个纯文本文件。 我们希望这个文本文件能被计算机…

锁相环(1)

PLL代表相位锁定环。顾名思义&#xff0c;如下图所示&#xff0c;PLL是一种具有反馈循环的电路&#xff0c;可将反馈信号的相/频率保持与参考输入信号的相/频率相同&#xff08;锁定&#xff09;。 如下图所示&#xff0c;如果参考输入和反馈输入之间存在相位差&#xff0c;则…

是德Keysight E4991A/e4991B射频阻抗/材料分析仪

Keysight E4991A 射频阻抗/材料分析仪提供终极阻抗测量性能和强大的内置分析功能。它将为评估 3 GHz 范围内组件的组件和电路设计人员的研发提供创新。E4991A 使用 RF-IV 技术&#xff0c;而不是反射测量技术&#xff0c;可在宽阻抗范围内进行更精确的阻抗测量。基本阻抗精度为…

在屎山代码中快速找到想要的代码法-锁表法(C#)

由于本人水平有限&#xff0c;文中有写得不对的地方请指正&#xff0c;本文的方法有些投机取巧&#xff0c;实在是没招的情况下可以酌情使用&#xff0c;如有侵权&#xff0c;请联系删除。 前几天接到一个需求&#xff0c;要在医嘱签署时对检验项目进行分方操作&#xff0c;分…

Linux Socket Buffer介绍

一. 前言 Linux内核网络子系统的实现之所以灵活高效&#xff0c;主要是在于管理网络数据包的缓冲器-socket buffer设计得高效合理。在Linux网络子系统中&#xff0c;socket buffer是一个关键的数据结构&#xff0c;它代表一个数据包在内核中处理的整个生命周期。 二. Socket Bu…

2.5|iot|第1章嵌入式系统概论|操作系统概述|嵌入式操作系统

目录 第1章&#xff1a; 嵌入式系统概论 1.嵌入式系统发展史 2.嵌入式系统定义* 3.嵌入式系统特点* 4.嵌入式处理器的特点 5.嵌入式处理分类 6.嵌入式系统的应用领域及嵌入式系统的发展趋势 第8章&#xff1a;Linux内核配置 1.内核概述 2.内核代码结构 第1章&#xf…

[安装之3] 笔记本加装固态和内存条教程(超详细)

由于笔记本是几年前买的了&#xff0c;当时是4000&#xff0c;现在用起来感到卡顿&#xff0c;启动、运行速度特别慢&#xff0c;就决定换个固态硬盘&#xff0c;加个内存条&#xff0c;再给笔记本续命几年。先说一下加固态硬盘SSD的好处&#xff1a;1.启动快 2.读取延迟小 3.写…