[网络编程]UDP协议,基于UDP协议的回显服务器

目录

1.UDP协议介绍

2.UDP协议在Java中的类

2.1DatagramSocket类

2.2DatagramPacket

3.回显服务器

3.1Sever端 

3.2Client端

1.UDP协议介绍

  UDP协议是一种网络协议,它是无连接的,全双工,并且是面向数据报,不可靠的一种协议。常用于在线视频播放,游戏这种实时性要求比较高的应用。或者无需可靠传输的应用,如DNS查询 SNMP等。一次UDP数据报报文传输的数据最大为64kb,实际上,UDP因为头部占用八个字节。所以可传输的精准大小为64kb-8b = 65507字节。

2.UDP协议在Java中的类

 UDP协议作为传输层协议,在Java中我们无需面对原生UDP协议,我们只需要调用Java封装好的类来使用UDP协议来传输和接受数据即可。在Java中有两个类,分别是DatagramSocket类和DatagramPacket类。

2.1DatagramSocket类

DatagramSocket用于创建Socket,绑定到端口号。它将网卡抽象成文件来方便程序猿来来操作。

DatagramSocket类的构造方法:
DatagramSocket类里的方法:

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

2.2DatagramPacket

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

DatagramPacket的构造方法:

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

DatagramPacket的方法:

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

3.回显服务器

为了方便大家理解和更好的使用UDP协议中的这两个类来实现网络编程,跨主机通信。

我们来写个简单的客户端-服务器程序-回显服务器,客户端将数据发送到服务器上,服务器在返回给客户端这个数据并且打印下来。主要目的是为了方便大家理解。

3.1Sever端 

在Sever端写之前,我们先讲明白几件事,首先就是我们的构造方法要不要指定端口号。答案是肯定的,因为这是服务器端,客户端想要访问它,肯定要有一个固定的地址,不然如何去访问,所以在构造方法中,我们直接从1024-65535这些端口号中选择一个给绑定上。

还有就是我们的主要逻辑过程:

1.接受数据并解析

2.将这个数据进行服务器的操作,即根据请求计算响应。

3.将响应返回给客户端。

明白了这些以后,我们开始编写代码

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;public class UdpEchoSever {DatagramSocket socket = null;public UdpEchoSever (int sort) throws SocketException {socket = new DatagramSocket(sort);//因为是服务器程序,所以我们要指定端口号}public void start() throws IOException {while (true){ //这里的while(true)是因为会有很多客户端来访问这个服务器,所以我们的服务器是7*24小时运行的System.out.println("服务器启动");byte[] bytes = new byte[1024];DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length); //创建一个数据报用来接收,这是一个输出型参数socket.receive(packet); //如果没有客户端进行访问,就会进行阻塞等待String request = new String(packet.getData(),0, packet.getLength()); //将这个数据报解析成字符串的形式String response = fun(request);DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,packet.getSocketAddress());//在构造的时候要将数据报转化为字符数组,并且指定IP地址和端口号发送,这里我们的IP地址和端口号,已经被存入到,packet.getSocketAddress()里面了System.out.printf("[%s :%d] req:%s,resp : %s\n",responsePacket.getAddress().toString(),responsePacket.getPort(),request,response);socket.send(responsePacket);}}private String fun(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoSever udpEchoSever = new UdpEchoSever(9090);udpEchoSever.start();}
}

3.2Client端

至于客户端,我们的逻辑就是,在构造方法里,要传入服务器的IP地址和端口号,以方便后续使用。

至于主方法,我们的大概思路分为以下几步
1.用户通过控制台输入,并且构造成DatagramPacket数据报,此时这个类里面应该有我们的数据和IP地址以及端口号

2.将这个数据报发送给服务器

3.从服务器拿到响应并且解析

4.将解析的响应打印出来

现在我们开始编程:

import javax.xml.ws.soap.Addressing;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class UdpEchoClient {DatagramSocket socket = null;int severport;String severIp;public UdpEchoClient(String severIp,int severport) throws SocketException { //在构造方法中传入服务器的IP地址和端口号socket = new DatagramSocket();this.severIp = severIp;this.severport = severport;}public void start() throws IOException {Scanner scanner = new Scanner(System.in);System.out.println("客户端启动");while (true){System.out.print("->");if(!scanner.hasNext()){ //用户输入到回车等这些空字符以后就结束break;}String request = scanner.next();DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(severIp),severport); //将数据以及IP地址(这里的IP地址是字符串,// 所以我们需要调用InetAddress.getByName())以及端口号也写进去socket.send(requestPacket);//发送到服务器byte[] bytes = new byte[1024];DatagramPacket responsPacket = new DatagramPacket(bytes,bytes.length);//同样是输出型参数,所以要先有一个空的字符数组socket.receive(responsPacket);//接收服务器传来的响应String respons = new String(responsPacket.getData(),0,responsPacket.getLength());//将响应转化为字符串System.out.println(respons);//打印下来}}public static void main(String[] args) throws IOException {UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);udpEchoClient.start();}
}

我们来看看运行结果

 可以看到客户端没有问题。我们再来看看服务器端的控制台:

也和我们预期的结果一样

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

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

相关文章

【UE Niagara】制作传送门_Part2

在上一篇(【UE Niagara】制作传送门_Part1)基础上继续完成传送门的外层轮廓效果 效果 步骤 1. 打开材质“M_BasicDot_Tans”,添加一个“DepthFade”节点 2. 对材质“M_SubUVMaster_Additive”创建材质实例,这里命名为“M_Portal…

文件传输中的MD5校验技术

1. 文件的MD5校验简介 文件的MD5校验是一种常用的文件完整性验证方法。MD5(Message Digest Algorithm 5)是一种广泛应用的哈希算法,它能够将任意长度的数据转换为固定长度的哈希值。在文件校验中,MD5算法通过计算文件的哈希值&…

常见的嵌入式面试问题解答!

1.关键字static的作用是什么?为什么static变量只初始化一次? ​1)修饰局部变量:使得变量变成静态变量,存储在静态区,存储在静态区的数据周期和程序相同, 在main函数开始前初始化,在…

最新版的Tuxera NTFS 2024 支持macOS 12系统

备受期待的Tuxera NTFS 2024 Mac中文版终于上线了,小编第一时间为您带来!Tuxera NTFS 2024 中文版是一款非常好用的NTFS读写工具,可以让您完整的读写兼容NTFS格式驱动器,对磁盘进行访问、编辑、存储和传输文件等。同时还包括开源磁…

C# wpf利用Clip属性实现截屏框

wpf截屏系列 第一章 使用GDI实现截屏 第二章 制作截屏框(本章) ______第一节 使用DockPanel制作截屏框 ______第二节 利用Clip属性实现截屏框(本节) 第三章 实现截屏框热键截屏 第四章 实现截屏框实时截屏 第五章 使用ffmpeg命令行实现录屏 文章目录 wp…

JavaScript基础之JavaScript引入方式

JavaScript引入方式 JavaScript 程序不能独立运行,它需要被嵌入 HTML 中,然后浏览器才能执行 JavaScript 代码。通过 script 标签将 JavaScript 代码引入到 HTML 中,一般以下方式: 外部方式内部方式JavaScript元素事件通过JavaScript伪URL引…

网络数据传输过程

先验知识:OSI模型 OSI网络模型实际上是参考模型,在实际中并不使用,在网络出现问题的时候,可以从一个宏观的整体去分析和解决问题,而且搭建网络的时候并不需要划分为7层,当今互联网广泛使用的是TCP/IP网络模…

最短代码实现随机打乱数组各个元素的顺序

//最短代码实现随机打乱数组各个元素的顺序 randomSortArr(arr []) {return [...Array(arr.length)].map((v, i) > arr.splice(Math.round(Math.random() * (arr.length - 1)), 1)[0]); },

Unity 建造者模式(实例详解)

文章目录 说明实例1:构建游戏角色实例2:构建游戏场景实例3:构建UI界面 说明 在Unity中,建造者模式(Builder Pattern)是一种创建型设计模式,它通过分离对象构建过程的复杂性,允许您以…

MySQL索引优化:深入理解索引下推原理与实践

随着MySQL的不断发展和升级,每个版本都为数据库性能和查询优化带来了新的特性。在MySQL 5.6中,引入了一个重要的优化特性——索引下推(Index Condition Pushdown,简称ICP)。ICP能够在某些查询场景下显著提高查询性能&a…

小程序学习-20

建议每次构建npm之前都先删除miniprogram_npm

Windows11家庭版上安装Hyper-V并导入虚拟机的方法

大纲 安装启用Hyper-V下载并安装启用 导入虚拟机代码地址 一般我们新买的电脑默认自带的是Windows家庭版。这个版本是没有Hyper-V的。如果安装自带Hyper-V的版本,则需要另外购买。但是我们还是有办法在Windows11的家庭版上安装和启用Hyper-V的。 安装启用Hyper-V …

前端模板字符串的使用

目录 1.说明 2.示例 3.总结 1.说明 模板字符串是用反引号()分隔的字面量,允许多行字符串,带有嵌入表达式的字符串插值和一种带标签的模板的特殊结构。 是增强版的字符串,在进行字符串拼接时,可以拼接固…

11 python快速上手

函数进阶 函数进阶1.参数的补充1.1 参数内存地址相关【面试题】1.2 函数的返回值是内存地址1.3 参数的默认值【面试题】1.4 动态参数 2. 函数和函数名2.1 函数做元素2.2 函数名赋值2.3 函数名做参数和返回值 3.返回值和print4. 作用域4.1 函数为作用域4.2 全局和局部4.3 global…

在CentOS 7 中配置NFS服务器

目录 1、克隆两个虚拟机 2、安装 NFS 服务 3、NFS 服务使用 1、克隆两个虚拟机 nfs-servernfs-client(修改ip地址)[rootxnode1 ~]# cd /etc/sysconfig/network-scripts/[rootxnode1 network-scripts]# vi ifcfg-eno16777736 #修改内容如下 BOOTPROT…

【QT+QGIS跨平台编译】之二:【zlib+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、zlib介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、zlib介绍 zlib是一套通用的解压缩开源库,提供了内存(in-memory)压缩和解压函数。zlib是一套通用的解压缩开源库,提供了内存(in-memory&am…

【小沐学GIS】基于C#绘制三维数字地球Earth(OpenGL)

🍺三维数字地球系列相关文章如下🍺:1【小沐学GIS】基于C绘制三维数字地球Earth(OpenGL、glfw、glut)第一期2【小沐学GIS】基于C绘制三维数字地球Earth(OpenGL、glfw、glut)第二期3【小沐学GIS】…

三、内存分配

1. JVM 简化架构概览 1.1 运行时数据区(即内存区域,又称 JVM 内存结构) 如上面的 JVM 简化架构图所示,内存区域分为如下五个部分(这五个部分统称为运行时数据区): PC 寄存器(又称程…

Python-setup进阶打包命令

一、setup.py文件的书写 这个资料有很多,不多赘述,setup 函数常用的参数如下: 基础描述信息: name 包名称(起一个响亮的名字)version (-V) 包版本author 程序的作者author_email 程序的作者的邮箱地址mai…

Kafka-服务端-DelayedOperationPurgatory

DelayedOperationPurgatory是一个相对独立的组件,它的主要功能是管理延迟操作。 DelayedOperationPurgatory的底层依赖于Kafka提供的时间轮实现。 我们可以使用JDK本身提供的java.util.Timer或是DelayQueue轻松实现定时任务的功能,为什么Kafka还要专门…