【JavaEE初阶】深入理解网络编程—使用UDP协议API实现回显服务器

前言

🌟🌟本期讲解关于TCP/UDP协议的原理理解~~~

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

🔥 你的点赞就是小编不断更新的最大动力                                       

🎆那么废话不多说直接开整吧~~~

目录

1.UDP的API使用 

1.1DatagramSocket

1.2DatagramPacket 

2.实现回显服务器

2.1概念

2.2服务器的操作过程

1.初始化服务器

2.读取请求并解析

3.根据请求实现响应

4.把响应返回给客户端

5.客户端的IP和端口号打印

6.主函数的实现

2.3客户端的操作过程

1.初始化客户端

2.控制台输入请求

3.构造请求并且发送

4.读取服务器的响应

5.主函数的实现

2.4回显服务器基本流程

2.5打印日志分析

3.总结

 

1.UDP的API使用 

1.1DatagramSocket

这里负责对Socket进行读写,借助网卡进行数据的读写操作;

这里的初始化方法有以下几种:

DatagramSocket()创建一个UDP数据报套接字Socket,绑定到本机的随意的一个端口(客户端)
DatagramSocket(int port)创建一个UDP数据报套接字Socket,绑定到本机的指定的一个端口(服务器)

 还包括实现那套接字的方法:

receive(DatagramPacket p)使用套接字实现数据的读取
send(DatagramPacket p)使用套接字实现数据的写入

注意:这里的DatagramPacket就是一个输出型参数 

1.2DatagramPacket 

       接着上面,小编提到这里的DatagramPacket是一个输出型参数,和前面实现文件IO的操作类似的,这里的就是一个UDP数据报,是接收和发送数据的基本单位;

2.实现回显服务器

2.1概念

回显服务器:相当于我们之前学习的输出hello world,这里的回显服务器代表的是没有任何逻辑过程,即客户端请求啥就直接响应啥;

2.2服务器的操作过程

1.初始化服务器

代码如下:

public class UDPServer {//构造方法private DatagramSocket socket=null;public UDPServer(int port) throws SocketException {//通过socket对网卡进行数据的操作socket=new DatagramSocket(port);}

注意

1.我们所有的对于网卡的操作就是借用这里的socket实现,这里的port是一个端口号,服务器是可控的所以这里就要指定一个端口号;

2.抛出异常,当端口号被一个进程占用了,那么端口号就创建失败了,一个端口号只能被一个进程占用,但是一个进程可以占用多个端口号;

2.读取请求并解析

代码如下:

public void start() throws IOException {System.out.println("服务器启动!");while (true) {// 每次循环, 就是处理一个请求-响应过程.// 1. 读取请求并解析DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);// 读到的字节数组, 转成 String 方便后续的逻辑处理.String request = new String(requestPacket.getData(), 0, requestPacket.getLength());

注意:

1.这里的死循环是为了表示,服务器是24小时不间断的,所以没有必要进行退出的操作;

2.通过DatagramPacket设置保存这里的读取到的字节信息,这是一个输出型参数;

3.此时的receive就能读取到UDP数据报的的内容,存放到requestPacket字节数组中;并且这里还知道原IP端口是啥(即数据从哪里来的)

4.最后将这里的字节类型的数据转化为字符串类型的数据,字节数组里不一定就是二进制的数据,还可能是文本类型的数据,使用string保存恰到好处;

3.根据请求实现响应

代码如下:

 String response = process(request);public String process(String request) {return request;}

注意:

由于回显服务器是没有业务逻辑的,所以在实现对应的响应的时候,直接放回输出的请求即可

4.把响应返回给客户端

代码如下:

 // 3. 把响应返回到客户端.//    构造一个 DatagramPacket 作为响应对象DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);

注意

1.这里的实现对于字符串的操作,把string的字节数组给提取出来;

2.这里还使用了socketAddress实现,得到INetAddress对象,包含了客户端的的IP和端口号,即客户端的数据报;

5.客户端的IP和端口号打印

代码如下:

  System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),requestPacket.getPort(), request, respond);

注意:

这里代表的就是客户端的IP,端口号,以及请求和响应;

6.主函数的实现

代码如下:

public static void main(String[] args) throws IOException {UDPServer udpServer=new UDPServer(9090);udpServer.start();}

注意:

 这里的9090是我们程序员规定的服务器的端口号;

2.3客户端的操作过程

1.初始化客户端

代码如下:

public class UDPClient {private DatagramSocket socket=null;private String ServerIP;private int ServerPort;public UDPClient(String serverIP,int serverPort) throws SocketException {this.ServerIP= serverIP;this.ServerPort=serverPort;socket=new DatagramSocket();}

注意:

这里要设置要请求的服务器的IP和端口号,因为发起请求就是要知道服务器在哪里;这里和上面日志的打印是一致的,请求的IP是客户端的本机IP,客户端是系统随机分配的;

2.控制台输入请求

代码如下:

 public void start() throws IOException {System.out.println("客户端启动");Scanner sc=new Scanner(System.in);while (true){System.out.println("->");if (!sc.hasNext()){break;}

注意:

这里和服务器是一致的,都是24小时不间断的,这里的sc.hashnext是为了表示没有更多的的输入了,那么就返回false去反后就跳出循环;

3.构造请求并且发送

代码如下:

String request=sc.next();DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(ServerIP),ServerPort);//来自哪里的信息socket.send(requestPacket);

注意:

这里就是通过字符串转为字节数据,并且指定发送的端口号和IP地址,最后通过send进行发送数据,请求服务器;

4.读取服务器的响应

代码如下:

// 4. 读取服务器的响应.DatagramPacket respondPacket=new DatagramPacket(new byte[1024],1024);socket.receive(respondPacket);String respond=new String(respondPacket.getData(),0,respondPacket.getLength());System.out.println(respond);

注意:

这里就规定传输的数据单位,通过接收服务器传来的响应,保存到字节数组里面,最后转为string字符串类型的数据,在实现打印

5.主函数的实现
public static void main(String[] args) throws IOException {UDPClient udpClient=new UDPClient("127.0.0.1", 9090);udpClient.start();}

注意:

这里的“127.0.0.1”是本机的IP地址,9090是我们输入的服务器端口号;

2.4回显服务器基本流程

如下图片的实现过程:

小编这里由于宽度不够就无法完全分开,请见谅~~~以上就是具体的实现过程

第一步:服务器启动进入receive,发现没有请求,那么就直接进入阻塞;

具体代码:

 DatagramPacket requestPacket=new DatagramPacket(new byte[1024],1024);//通过接收的方法进行数据的传入socket.receive(requestPacket);

 第二步:客户端进入循环,执行到sc.hashnext进入阻塞,知道用户输入内容;

具体代码:

 System.out.println("->");if (!sc.hasNext()){break;}

第三步:输入请求的内容,转化为字节类型数据,指定服务器IP和端口号,发送请求

具体代码:

 String request=sc.next();DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(ServerIP),ServerPort);//来自哪里的信息socket.send(requestPacket);

第四步:服务器解除阻塞,读取DatagramRocket对象,构造string需求,根据需求执行响应操作,最后返回构造响应对象,并进行send发送的操作;这个过程客户端阻塞

具体代码:

 String request=new String(requestPacket.getData(),0,requestPacket.getLength());//注意这里的长度是字节的长度,不是字符串的长度//进行响应的操作String respond=process(request);//发送响应,转化为面向数据包的类型DatagramPacket respondPacket=new DatagramPacket(respond.getBytes(),respond.getBytes().length,requestPacket.getSocketAddress());//最后发送这个数据socket.send(respondPacket);

第五步:客户端接收服务器传来的数据,存储在字节数组中,然后转化为字符串数据类型,实现打印在控制台上;

具体代码:

 DatagramPacket respondPacket=new DatagramPacket(new byte[1024],1024);socket.receive(respondPacket);String respond=new String(respondPacket.getData(),0,respondPacket.getLength());System.out.println(respond);

2.5打印日志分析

这里我们启动服务器和客户端后,进行输入:

这里我们就可以看到输出一个nihao那么就返回一个nihao,那么我们可以看看服务器的打印日志

如下图:

此时注意前面两个第一个是“127.0.0.1”是我们自己的本机IP地址,并且后面这个就是请求的端口;

3.总结

 💬💬本期小编主要讲解了UDP的API的使用,并且通过UDP提供的API实现回显服务器的实现,当然这里设计到服务器和客户端两边的实现过程~~~

具体代码已上传gitee,代码在这里:network: 网络编程

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!! 


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                             😊😊  期待你的关注~~~

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

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

相关文章

oracle_查询建表语句

查询建表语句 SELECTdbms_metadata.get_ddl ( TABLE, <table_name> ) FROMdualdbms_metadata.get_ddl&#xff1a;是Oracle提供的一个函数&#xff0c;用于获取数据库对象的DDL语句&#xff0c;它允许你查看或导出数据库对象的创建脚本‘TABLE’&#xff1a; 是这个函数…

时间复杂度记法(大O记法)相关知识简记

一、概念 大 O 本是一个数学概念。 大 O 记法可用来描述一个函数的增长率的上限”&#xff0c;或者“如果函数 g(x)的增长速度不比函数 f(x)快&#xff0c;那么就称 g 属于 O( f )。 大 O 记法不只是用固定的数字来表示算法的步数&#xff0c;而是基于要处理的数据量来描述算…

Substrate 网络层深度解读:libp2p 助力去中心化点对点高效通信

区块链中需要高效的通信工具来确保节点之间的顺畅交互。而 libp2p 正是开发者在点对点通信中不可或缺的框架&#xff0c;提供了强大的模块化功能&#xff0c;使得去中心化网络中的消息传递变得更加灵活且安全。在 Substrate 中&#xff0c;libp2p 的集成帮助开发者轻松实现各种…

从0开始深度学习(12)——多层感知机的逐步实现

依然以Fashion-MNIST图像分类数据集为例&#xff0c;手动实现多层感知机和激活函数的编写&#xff0c;大部分代码均在从0开始深度学习&#xff08;9&#xff09;——softmax回归的逐步实现中实现过 1 读取数据 import torch from torchvision import transforms import torchv…

查找与排序-交换排序

交换排序是基于“比较”和“交换”两种操作来实现的排序方法 。 由于选择“比较”的基准元素不同&#xff0c;可将交换排序分为以下两种&#xff1a; 冒泡排序快速排序 一、冒泡排序 1.冒泡排序基本思想 因为其实现与气泡从水中往上冒的过程类似而得名。 每一趟的…

基于SpringBoot+Vue+uniapp微信小程序的垃圾分类系统的详细设计和实现(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

MYSQL 表对表快速迁移-直接拷贝表空间文件.ibd进行迁移

数据无价&#xff0c;操作前&#xff0c;建议先备份 前提条件 表结构一致&#xff1a; 源数据库和目标数据库中的表结构必须完全相同。这包括表的列定义、索引、约束等。 表使用 InnoDB 存储引擎&#xff1a; 这种迁移方法仅适用于使用 InnoDB 存储引擎的表&#xff0c;因为 .…

Redux (八) 路由React-router、嵌套路由、路由传参、路由懒加载

文章目录 一、React-Router的基本使用1. 安装及基本使用(路由映射配置)2. 路由跳转Link与NavLink3. Navigate导航4. 处理路径不存在的情况 二、嵌套路由三、手动跳转 (类似编程式路由导航)1. 函数式组件2. 类组件实现手动跳转 四、路由传参1. 路径设置占位符(params)2. search传…

Java面试指南:Java基础介绍

这是《Java面试指南》系列的第1篇&#xff0c;本篇主要是介绍Java的一些基础内容&#xff1a; 1、Java语言的起源 2、Java EE、Java SE、Java ME介绍 3、Java语言的特点 4、Java和C的区别和联系&#xff1f; 5、面向对象和面向过程的比较 6、Java面向对象的三大特性&#xff1a…

leetcode30:串联所有单词的字串

给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab","cd","ef"]&#xff0c; 那么 "abcdef…

1. 解读DLT698.45-2017通信规约--预连接响应

国家电网有限公司企业标准&#xff0c;面向对象的用电信息数据交换协议DLT698.45-2017 为提高用电信息采集系统的业务适应性、采集效率、安全性和数据溯源性&#xff0c;规范用电信息数据交换协议的通信架构、数据链路层、应用层、接口类与对象标识&#xff0c;制定本标准。 …

Linux系统:(Linux系统概述与安装)

硬件计算机硬件是指计算机系统中所有物理部件的总称。包括计算机主机、显示器、键盘、鼠标、内存、硬盘、处理器、主板等等。这些硬件部件是计算机系统运行的基础 不管是电脑系统(个人电脑、服务器等)、还是移动端操作系统(手机、平板等)。它的功能就是做为用户和硬件之间的桥梁…

前端求职简历-待补充

当然可以&#xff0c;针对大厂的前端岗位&#xff0c;一个吸引人的简历应该突出你的技术能力、项目经验、教育背景以及任何能体现你学习能力和团队协作能力的证明。以下是一个简历大纲示例&#xff0c;你可以根据自己的实际情况进行调整&#xff1a; 个人信息 姓名联系方式&a…

图文深入介绍oracle资源管理(续)

1. 引言&#xff1a; 本文将承接上篇继续深入介绍oracle资源管理。本文重点介绍如何使用oracle资源管理器管理好DB。 2. 资源管理器&#xff1a; 可以使用图形界面 OEM$或命令行调用 DBMS RESOURCE MANAGER 程序包的过程进行数据库资源管理。 调用资源管理器的先决条件&…

瑞数后缀加密怎么处理

前言&#xff1a; 瑞数我们经常补环境通过&#xff0c;但是遇到瑞数后缀不知道怎么处理 就拿瑞数4来讲 解决方法&#xff1a; &#xff08;1&#xff09;传明文加密参数 一般情况&#xff0c;我们传明文加密参数也能访问 &#xff08;2&#xff09;再补环境基础调用open …

基于stm32的4G模块点灯实验

led模块功能封装 #include "led.h" #include "sys.h"//初始化GPIO函数 void led_init(void) {GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOB_CLK_ENABLE();//调用GPIO初始化函数gpio_initstruct.Pin GPIO_PIN_8 | GPIO_PIN_9;gpio_inits…

排序算法 —— 直接插入排序

目录 1.直接插入排序的思想 2.直接插入排序的实现 实现分析 实现代码 3.直接插入排序的分析 时间复杂度分析 空间复杂度分析 稳定性 1.直接插入排序的思想 直接插入排序的思想就是把待排序的元素按其关键码值的大小依次插入到一个已经排好序的有序序列中&#xff0c…

YOLOv11改进策略【卷积层】| SAConv 可切换的空洞卷积 二次创新C3k2

一、本文介绍 本文记录的是利用SAConv优化YOLOv11的目标检测网络模型。空洞卷积是一种在不增加参数量和计算量的情况下,通过在卷积核元素之间插入空洞来扩大滤波器视野的技术。并且为了使模型能够适应不同尺度的目标,本文利用SAConv将不同空洞率卷积结果进行结合,来获取更全…

pycharm调试带参数命令行的程序

点击 run configuration 点击加号&#xff0c;选择python name填写程序名字&#xff0c;script填写程序路径&#xff0c;下一行填写传入的参数 点击apply&#xff0c;再点ok&#xff0c;即可debug 参考&#xff1a; pycharm 调试模式下命令行参数的传递_pycharm debug传参 ya…

项目实战:构建 effet.js 人脸识别交互系统的实战之路

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀构建 effet.js &#x1f4d2;1. 什么是effet.js&#x1f4dc;2. 为什么需要使用effet.js&#x1f4dd;3. effet.js的功能&#x1f4da;4. 使用…