面向数据报编程-UDP协议

news2024/11/15 20:31:27

目录

前言:

1.UDP协议API

1.1UDP编程原理

1.2DatagramSocket类

(1)DatagramSocket构造方法

(2)DatagramSocket普通方法

1.3DatagramPacket类

(1)DatagramPacket构造方法

(2)DatagramPacket普通方法

1.4InetSocketAddress类

2.代码案例

2.1服务器端

2.2客户端

2.3运行结果


前言:

在网络编程-002节中已经介绍了有关传输层UDP协议的基本知识,本节不再介绍有关UDP协议的基础内容,主要讲UDP协议的重点API及其使用方法,通过案例的形式完善。

序列:网络编程 - 003


1.UDP协议API

1.1UDP编程原理

 对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且一次发送全部数据报,一次接收全部的数据报。

Java中使用UDP协议通信,主要基于DatagramSocket类来发送或接收数据报套接字,并使用DatagramPacket作为创建的UDP数据报,DatagramPacket类对象就是UDP协议中Socket的数据报。

1.2DatagramSocket类

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

(1)DatagramSocket构造方法

构造方法如下:

构造方法方法说明
DatagramSocket()创建一个UDP数据报套接字的Socket,绑定到本机一个随机端口(一般用于客户端)
DatagramSocket(int port)创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端)
(2)DatagramSocket普通方法

普通方法如下:

方法方法说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报,该方法会阻塞等待)
void send(DatagramPacket p)从此套接字发送数据报包(不会阻塞等待,直接发送)
void close()关闭此数据报套接字

1.3DatagramPacket类

(1)DatagramPacket构造方法

构造方法如下:

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

其中buf数组为输出型参数,offset默认为零,可以省略。

(2)DatagramPacket普通方法

普通方法如下:

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

1.4InetSocketAddress类

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

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

方法方法说明
InetSocketAddress(InetAddress addr , int port)创建一个Socket地址,包含IP地址和端口号

2.代码案例

 利用传输层的UDP协议,我们可以实现一个实例。在Idea控制台手动输入字符串内容,从客户端发送给服务器端,然后服务器端不做任何处理,直接再次返回给客户端同样的字符串。

2.1服务器端

代码如下:

public class EchoServer {//服务器端
    //1、创建一个DatagramSocket对象
    DatagramSocket socket = null;
    public EchoServer(int port) throws SocketException {//服务器端需要自己指定端口号
        socket = new DatagramSocket(port);//这么写就是手动指定端口号
        //socket = new DatagramSocket();//这么写就是系统自动分配端口号
    }

    public void start() throws IOException {
        System.out.println("服务器启动...");
        while (true){
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            //requestPacket这个对象是用来承载数据的,在创建的时候需要创建一块内存空间来保存数据
            socket.receive(requestPacket);
            //当前完成的receive之后,数据是以二进制的形式存储到DatagramPacket中
            //还需要把这个二进制的数据转化成字符串的形式
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            //范围为0到requestPacket.getLength(),requestPacket.getLength()表示数据的真实长度
            //2、根据请求,计算响应(服务器端最核心的作用)
            String response = process(request);
            //3、把响应写回到客户端
            //搞一个响应对象,DatagramPacket
            //把DatagramPacket构造刚才的数据,再通过send返回
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),
                    0,
                    response.getBytes().length,
                    requestPacket.getSocketAddress());//指定数据内容,同时指定数据要发给谁
            socket.send(responsePacket);
            //4、打印一个日志,把这次的数据交互的详情给打印出来
            System.out.printf("[%s:%d] req = %s,resp = %s\n",
                    responsePacket.getAddress().toString(),
                    responsePacket.getPort(),
                    request,
                    response);
        }
    }
    public String process(String request) {//请求是啥样,响应就是啥样
        //回转响应的方法
        return request;
    }
    public static void main(String[] args) throws IOException {
        EchoServer server = new EchoServer(9090);//实例测试
        server.start();
    }
}

2.2客户端

代码如下:

public class EchoClient {//客户端
    private DatagramSocket socket = null;
    private String serverIP = "";
    private int serverPort = 0;
    public EchoClient(String ip,int port) throws SocketException {
        //创建这个对象不能手动指定端口
        socket = new DatagramSocket();
        //由于 UDP自身不会持有对端信息,就需要在应用程序里,把对端的情况给记录下来
        //这里咱们主要记录对端的ip和端口
        serverIP = ip;
        serverPort = port;
    }
    public void start() throws IOException {
        System.out.println("客户端启动...");
        Scanner scanner = new Scanner(System.in);
        while (true){
            //1、控制台读取数据,作为请求
            System.out.println(" -> ");
            String request = scanner.next();
            //2、把请求的内容构造成DatagramSocket对象,发送给服务器
            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 {
        EchoClient client = new EchoClient("127.0.0.1",9090);
        client.start();
    }
}

2.3运行结果

在同时运行服务器端和客户端两段代码后,在客户端的控制台输入字符串,结果如图所示:

客户端:

服务器端:


以上便是对传输层的UDP协议API介绍,并举例说明了UDP协议的具体用法。

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

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

相关文章

电商小程序03登录页面开发

目录 1 创建应用2 创建页面3 首页功能搭建4 登录页搭建5 设置叠加效果总结 小程序开发在经过需求分析和数据源设计之后,就可以进入到页面开发的阶段了。首先我们需要开发登录的功能。 登录功能要求用户输入用户名和密码,勾选同意用户协议和隐私协议&…

SAP-PS-02-004利润中心移除分配公司代码

问题描述 在用KE51创建利润中心时,如果不采用“参考创建”的方式,SAP默认将所有公司代码分配给此利润中心。 上图中,L100003利润中心分配了1000、1001、1002公司,但是实际需求是:L100003只需要分配1000公司。 解决方法…

elasticsearch增删改查

一、数据类型 1、字符串类型 (1)text (2)keyword 2、数值类型 (1)long、integer、short、byte、float、double 3、日期类型 (1)date 4、布尔类型 (1&#xff0…

ChatGPT高效提问—prompt常见用法(续篇九)

ChatGPT高效提问—prompt常见用法(续篇九) ​ 如何准确地向大型语言模型提出问题,使其更好地理解我们的意图,从而得到期望的答案呢?编写有效的prompt的技巧,精心设计的prompt,获得期望的的答案。 1.1 增加条件 ​ 在各种prompt技巧中,增加条件是最常用的。在prompt中…

基于JavaWeb的网上订餐项目

点击以下链接获取源码: https://download.csdn.net/download/qq_64505944/88825723?spm1001.2014.3001.5503 Java项目-16 浏览商品,会员登录,添加购物车,进行配送等功能 文件代码功能介绍 1.Src下的java文件存放的我们后端的…

基于PHP网上图书销售商城系统qo85w

软件体系结构方案:由于本系统需要在不同设备上都能运行,而且电脑配置要求也要越低越好,为了实现这一要求,经过考虑B/S结构成为最佳之选。使用B/S结构的系统可以几乎在任何电脑上运行,只要浏览器可以正常工作就可以正常…

C++ //练习 5.12 修改统计元音字母的程序,使其也能统计空格、制表符和换行符的数量。

C Primer(第5版) 练习 5.12 练习 5.12 修改统计元音字母的程序,使其也能统计空格、制表符和换行符的数量。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 /******************************…

【JavaScript 】finally() 方法和Filter() 方法

JavaScript 中的finally() 方法 finally是 JavaScript 构造中使用的方法try-catch。try它在and阻塞之后执行catch,无论 Promise 是已履行还是已拒绝。该函数的主要作用是执行必要的清理任务并向用户传达消息。一个常见的用例可能是通知用户“您的请求已被处理”&am…

使用client-only 解决组件不兼容SSR问题

目录 前言 一、解决方案 1.基于Nuxt 框架的SSR应用 2.基于vue2框架的应用 3.基于vue3框架的应用 二、总结 往期回顾 前言 最近在我的单页面SSR应用上开发JSON编辑器功能,在引入组件后直接客户端跳转OK,但是在直接加载服务端渲染的时候一直报这…

【机器学习】单变量线性回归

文章目录 线性回归模型(linear regression model)损失/代价函数(cost function)——均方误差(mean squared error)梯度下降算法(gradient descent algorithm)参数(parame…

微信小程序(三十九)表单信息收集

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.表单收集的基本方法 2.picker的不足及解决方法 源码&#xff1a; index.wxml <!-- 用户信息 --> <view class"register"><!-- 绑定表单信息收集事件--><form bindsubmit"…

信号——block+pending+handler表

信号 注意 &#xff1a;这由三张表&#xff0c;block只能添加修改&#xff0c;pending只能获取 , handler只能修改 基础知识 抵达——> 执行 / 忽略sigset_t 信号集被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作 信号集操作 #include &…

第75讲Avatar头像FooterHome实现

Avatar头像实现 avatar&#xff1a; <template><el-dropdown><span class"el-dropdown-link"><el-avatar shape"square" :size"40" :src"squareUrl" /></span><template #dropdown><el-drop…

【MySQL进阶之路】生产案例:数据库无法连接,Too many connections

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

6 scala-面向对象编程基础

Scala 跟 Java 一样&#xff0c;是一门面向对象编程的语言&#xff0c;有类和对象的概念。 1 类与对象 与 Java 一样&#xff0c;Scala 也是通过关键字 class 来定义类&#xff0c;使用关键字 new 创建对象。 要运行我们编写的代码&#xff0c;同样像 Java 一样&#xff0c;…

C#,最大公共子序列(LCS,Longest Common Subsequences)的算法与源代码

1 最大公共子序列 最长的常见子序列问题是寻找两个给定字符串中存在的最长序列。 最大公共子序列算法&#xff0c;常用于犯罪鉴定、亲子鉴定等等的 DNA 比对。 1.1 子序列 让我们考虑一个序列S<s1&#xff0c;s2&#xff0c;s3&#xff0c;s4&#xff0c;…&#xff0c;…

项目02《游戏-13-开发》Unity3D

基于 项目02《游戏-12-开发》Unity3D &#xff0c; 任务 &#xff1a;宠物系统 及 人物头像血条 首先在主面板MainPanel预制体中新建一个Panel&#xff0c; 命名为PlayerInfo 新建Image&#xff0c;作为头像 新建Slider&#xff0c;作为血条 对Panel组件添加一个水…

中年低端中产程序员从西安出发到海南三亚低成本吃喝万里行:西安-南宁-湛江-雷州-徐闻-博鳌-陵水-三亚-重庆-西安

文章大纲 旅途规划来回行程的确定南宁 - 北海 - 湛江轮渡成为了最终最大的不确定性&#xff01;感谢神州租车气温与游玩地点总体花费 游玩过程出发时间&#xff1a;Day1-1月25日星期四&#xff0c;西安飞南宁路途中&#xff1a;Day2-1月26日星期五&#xff0c;南宁-湛江-住雷州…

算法学习——LeetCode力扣二叉树篇1

算法学习——LeetCode力扣二叉树篇1 144. 二叉树的前序遍历 144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; 描述 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&a…

猫头虎分享已解决Bug | Kotlin Error: Unresolved reference: name

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …