【JavaEE】——Udp翻译器的实现(回显服务器)

 8e19eee2be5648b78d93fbff2488137b.png

阿华代码,不是逆风,就是我疯

你们的点赞收藏是我前进最大的动力!!

希望本文内容能够帮助到你!!

目录

一:引入

1:基本概念

二:UDP socket API使用

1:socket文件

2:DatagramSocket类

(1)构造方法

(2)方法

3:DatagramPacket类

三:回显服务器——服务器

1:引入(必看)

2:服务器响应代码

(1)注释版本

(2)无注释版本

3:细节补充

4:特点

四:回显服务器——客户端

1:代码

(1)注释版本

(2)无注释版本

2:注意点

五:回显服务器过程文字梳理

六:知识补充


前引:本文代码建议反复敲打至少3遍!!!!

一:引入

1:网络编程的基本概念

网络编程就是通过写代码来完成基于网络的跨主机通信

本质上是学习传输层给应用层提供的一系列的API,通过API把数据交给传输层,在经过层层封装之后,通过网卡,把数据发送出去。

这里使用的API是传输层提供的,传输层涉及到的主要协议有两个:TCP和UDP

后面通过代码详细理解这些特点

①有/无连接:这里的“连接”是虚拟的,抽象的连接

例:打电话——打过去对方接才能通话;微信发消息不管对面在不在线,消息都发出去了

②可/不可靠传输:可以知道数据到没到达对方

③面向字节流:传输数据的基本单位就是字节

④面向数据报:传输的的基本单位是一个“数据报”——由一系列字节构成的特定结构UDP

⑤全双工:可以双向通信

⑥半双工:只能单向通信

客户端:发送请求的一方,发送的数据叫做“请求”

服务器:被动接受请求的一方,给客户端返回的数据叫做“响应”

客户端和服务器之间的交互有这几种模式:“一问一答”,“一问多答”,“多问一答”,“多问多答”,

二:UDP socket API使用

引入:UDP核心类有两个DatagramSocket,DatagramPacket

1:socket文件

操作系统中有一类文件就叫做socket文件,区别于放在硬盘上的普通文件,socket文件是放在“网卡”这样的硬件设备上——通过网卡发送数据,就是写socket文件;接受数据,就是读socket文件

2:DatagramSocket类

(1)构造方法

(2)方法

3:DatagramPacket类

UDP面向数据报,每次发送和接收数据的基本单位就是一个UDP数据报

(1)构造方法

下面这个图建议读完代码后再进行理解

(2)方法

三:回显服务器——服务器

1:引入(必看)

以下代码是实现一个“回显服务器”——是网络编程中的“hello world”,但是对新手小白并不友好

大致流程为:客户端发出请求,服务器收到客户端的请求,完成业务并返回响应,客户端接受响应

先附赠上服务器的代码,(按照步骤去边理解边敲)(重在理解,重在理解)

2:服务器响应代码

(1)注释版本

package network;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-10-07* Time: 17:20*/
public class UdpEchoServer {//1:创建DatagramSocket对象private DatagramSocket socket = null;//socket:插槽插座//2:构造方法,服务器一启动,就要关联/绑定上一个操作系统中的端口号(服务器的端口号哦啊通常由程序员指定)//抛出的异常通常为scoket创建失败public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);//端口号port}//3:服务器启动逻辑//5:抛异常,网络编程socket本质上也是IOpublic void start() throws IOException {System.out.println("服务器启动");while(true){//3:创建一个数据报,它是每次发送数据和接收数据的一个基本单位// 参数为输出型参数,字节数组,对应UDP的载荷部分,一开始是空的DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);//4;socket读网卡能读到一个UDP数据报(里面会包含数据源IP,源端口),放到requestPacket(数据报)对象中//如果没有接受到请求那么就会阻塞等待,此处收到的数据是先存到socket文件的内存缓冲区中。非硬盘socket.receive(requestPacket);//5:基于字节数组构造String对象,数组中的数据可能是文本数据(给String刚好)也可能是二进制数据(Java也能保存)//这里的长度是有效长度String request = new String(requestPacket.getData(),0,requestPacket.getLength());//6:根据请求计算响应String response = process(request);//7:把响应(String)字节给拎出来,构造成一个DatagramPacket数据报,在传入socket对象(因为4中我们说过收到请求时,socket能读到源IP和源端口)//这时我们把这个源IP和源端口,作为响应的目的IP和目的端口(确认客户端的发出请求的位置),返回回去//注:response.length()单位是字符,此处单位是字节DatagramPacket responsePacket = new DatagramPacket(response.getBytes() , response.getBytes().length , requestPacket.getSocketAddress());socket.send(responsePacket);}}//7:构造响应,这里是回显服务器,所以就是单纯的returnprivate String process(String request) {return request;}}

(2)无注释版本

package repeat2;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-10-10* Time: 18:28*/
public class UdpServer {private DatagramSocket socket = null;public UdpServer(int port) throws SocketException {socket = new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动");while(true){DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//转化为字符串String request = new String(requestPacket.getData(),0,requestPacket.getLength());String response = process(request);DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf("[%s,%d]  request: %s  response: %s\n ",requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}public String process(String request){return request;}public static void main(String[] args) throws IOException {UdpServer server = new UdpServer(9096);server.start();}
}

3:细节补充

这里在补充一些细节:

①创建完socket对象后,可以通过socket对象来操作网卡(具体:因为socket对象是在内存中的,针对这个内存对象进行操作就可以影响到网卡)

②构造方法(还有无参的上面有写)中的参数,是我们指定的,进程一启动就要绑定上操作系统中的端口号,这个端口号是一个整数,用来区分一个主机上的进行网络通信的不同程序

一个端口号只能被一个进程绑定,但是一个进程可以绑定多个端口号(像极了爱情~~,爱情中宁死不做端口号~~)

③SocketException,类似端口号被别的进程占用就会报异常

④因为服务器需要不停的运作,所以while一直循环

⑤数据报中的数组就是载荷部分

⑥receive有阻塞等待功能

⑧数据报的位置在socket对象的内存缓冲区中

⑨构造响应数据报

4:特点

上述代码可以体现出UDP是——

(1)无连接通信

UDP的DAtagramSocket自身并不需要保存对端的IP和端口,对端IP和端口在数据报中就已经包含,另外代码中也没有“建立连接”和“接受连接”这种操作

(2)不可靠数据——代码没体现(略)

(3)面向数据报

send方法和receive方法都是以DatagramPacket为基本单位的

(4)全双工

一个socket既可以发送数据报又可以接受数据报(属于是自力更生了)

四:回显服务器——客户端

1:代码

(1)注释版本

package network;import java.io.IOException;
import java.net.*;
import java.util.Scanner;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-10-07* Time: 17:20*/
public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;public UdpEchoClient(String serverIp , int serverPort) throws SocketException {this.serverIp = serverIp;this.serverPort = serverPort;socket = new DatagramSocket();//传入参数为请求的目的ip和目的端口,源ip为本机ip源端口为系统分配的端口}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner = new Scanner(System.in);while(true){System.out.print("->");if (!scanner.hasNext()){//如果没有输入的话就结束循环break;}String request = scanner.next();//人为输入请求DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);//指定服务器的ip和端口,分开的socket.send(requestPacket);DatagramPacket responsePacket = new DatagramPacket(new byte[4096] , 4096);socket.receive(responsePacket);//转化为字符串String response = new String(responsePacket.getData(),0,responsePacket.getLength());//内置getLength()获取length成员变量System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);client.start();}
}

(2)无注释版本

package repeat2;import java.io.IOException;
import java.net.*;
import java.util.Scanner;/*** Created with IntelliJ IDEA.* Description:* User: Hua YY* Date: 2024-10-10* Time: 18:29*/
public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;public UdpEchoClient(String serverIp , int serverPort) throws SocketException {this.serverIp = serverIp;this.serverPort = serverPort;socket = new DatagramSocket();}public void start() throws IOException {System.out.println("客户端启动");Scanner scanner = new Scanner(System.in);while(true){System.out.print("->");if(!scanner.hasNext()){break;}String request = scanner.next();DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);//接收响应DatagramPacket responsePacket = new DatagramPacket(new byte[4096] , 4096);socket.receive(responsePacket);String response = new String(responsePacket.getData(),0,responsePacket.getLength());System.out.println(response);//}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1",9096);client.start();}
}

2:注意点

(1)服务器端口号需要手动指定,是确保客户端可以找到服务器,客户端的端口号是操作系统的内核随机分配的 (确保分配的端口号是空闲可用的)

(2)Scanner从控制台读取字符串最好使用next非nextLine

(如果是从文件读取就无所谓了)

①next读取

②nextLine读取

(3).length和.length()方法的区别

五:回显服务器过程文字梳理

六:知识补充

1:.length和.length()的区别

引用文章java中length和length()的区别_length变量与length函数 java-CSDN博客

2:字符串转数组

七:易错的地方

构造String用getData(),有0-多少范围,

构造DatagramPacket用getBytes(),范围为getBytes().length

服务器获取客户端地址用:.getSocketAddress()

客户端获取服务器地址用:InetAddress.getByName(),serverPort

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

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

相关文章

正点原子讲解SPI学习,驱动编程NOR FLASH实战

配置SPI传输速度时,需要先失能SPI,__HAL_SPI_DISABLE,然后操作SPI_CR1中的波特率设置位,再使能SPI, NM25Q128驱动步骤 myspi.c #include "./BSP/MYSPI/myspi.h"SPI_HandleTypeDef g_spi1_handler; /* SPI句柄 */void spi1_init(void) {g_spi…

使用Hugging Face中的BERT进行标题分类

使用Hugging Face中的BERT进行标题分类 前言相关介绍出处基本原理优点缺点 前提条件实验环境BERT进行标题分类准备数据集读取数据集划分数据集设置相关参数创建自己DataSet对象计算准确率定义预训练模型定义优化器训练模型保存模型测试模型 参考文献 前言 由于本人水平有限&…

动态规划-简单多状态dp问题——面试题17.16.按摩师

多状态问题的核心就是每个位置不止有一个状态,因此需要多个dp表表示不同状态对应位置的值,然后根据题目考虑特定情况写出状态转移方程即可 1.题目解析 题目来源:面试题17.16.按摩师——力扣 测试用例 2.算法原理 1.状态表示 这里与路径问…

【CSS in Depth 2 精译_047】7.2 CSS 响应式设计中的媒体查询原则(上):深入理解媒体查询的类型

当前内容所在位置(可进入专栏查看其他译好的章节内容) 【第七章 响应式设计】(概述) 7.1 移动端优先设计原则(上篇) 7.1.1 创建移动端菜单(下篇)7.1.2 给视口添加 meta 标签&#xf…

MATLAB - 机器人机械臂设计轨迹规划器

系列文章目录 前言 本示例介绍了一种设计抓取和轨迹规划器的方法,该规划器可用于垃圾箱拣选系统。 在机器人技术中,垃圾箱拣选包括使用机械手从垃圾箱中取出物品。智能垃圾箱拣选是这一过程的高级版本,具有更强的自主性。使用摄像系统感知部件,规划器生成与场景相适应的无碰…

NASA:ARCTAS 区域的二级 FIRSTLOOK 气溶胶产品子集。 它包含气溶胶光学深度和粒子类型,以及相关的大气数据

目录 简介 信息 代码 引用 网址推荐 知识星球 机器学习 MISR L2 FIRSTLOOK Aerosol Product subset for the ARCTAS region V001 简介 这是 ARCTAS 区域的二级 FIRSTLOOK 气溶胶产品子集。 它包含气溶胶光学深度和粒子类型,以及相关的大气数据,…

关于摩托车一键启动无钥匙进入、智能科技创新

摩托车一键启动无钥匙进入功能 一、工作原理 摩托车的一键启动无钥匙进入功能采用了世界最先进的RFID无线射频技术和最先进的车辆身份编码识别系统,率先应用小型化、小功率射频天线的开发方案,并成功融合了遥控系统和无钥匙系统,沿用了传统…

在 MTT GPU 上使用 llama.cpp 推理

大语言模型因其出色的自然语言理解和生成能力而迅速被广泛使用,llama.cpp 大幅降低了进行大语言模型推理的门槛,MTT GPU 同样也是 llama.cpp 支持的运行平台,能够充分利用硬件的性能来助力用户的大语言模型应用。 本文主要介绍了如何在摩尔线…

出处不详 取数游戏

目录 取数游戏题目描述背景输入输出数据范围 题解解法优化 打赏 取数游戏 题目描述 背景 两人将 n n n个正整数围成一个圆环,规则如下: 第一名玩家随意选取数字;第二名玩家从与第一名玩家相邻的两个数字中选择一个;而后依次在…

用Arduino单片机制作一个简单的音乐播放器

Arduino单片机上有多个数字IO针脚,可以输出数字信号,用于驱动发声器件,从而让它发出想要的声音。蜂鸣器是一种常见的发声器件,通电后可以发出声音。因此,单片机可以通过数字输出控制蜂鸣器发出指定的声音。另外&#x…

【尚硅谷】FreeRTOS学笔记(更新中更新时间2024.10.12)

在网上看到的一段很形象的描述,放在这里给大家娱乐一下。 裸机开发:n个人拉屎,先进去一个拉完,下一个再来。看门狗:如果有人拉完屎还占着,茅坑刷视频,把他拖出去中断系统:n个人拉屎&…

Python | Leetcode Python题解之第477题汉明距离总和

题目: 题解: class Solution:def totalHammingDistance(self, nums: List[int]) -> int:n len(nums)ans 0for i in range(30):c sum(((val >> i) & 1) for val in nums)ans c * (n - c)return ans

数通--3

一、动态路由 内部 路由器之间要互联互通,必须遵循相同的协议 企业内部用 IGP,企业之间用BGP RIP(已淘汰,不考) 距离就是长短,矢量就是方向,即路由的出接口 一台路由器 A 配好RIP,…

C++面试速通宝典——25

473. HTTP如何减少重定向请求 重定向请求: ‌‌‌‌  服务器上的一个资源可能由于迁移、维护等原因从url1移至url2后,而客户端不知情,他还是继续请求url1,这时服务器不能粗暴地返回错误,而是通过302响应码和Locati…

鸿蒙--商品列表

这里主要利用的是 List 组件 相关概念 Scroll:可滚动的容器组件,当子组件的布局尺寸超过父组件的视口时,内容可以滚动。List:列表包

Appium Device Farm安装教程

环境要求:Appium version ≥ 2.4.X 安装appium npm install -g appium2.11.3 如果安装提示如下问题 npm error code EEXIST npm error syscall rename npm error path /Users/wan/.npm/_cacache/tmp/d5787519 npm error dest /Users/wan/.npm/_cacache/content-…

鸿蒙--WaterFlow 实现商城首页

目录结构 ├──entry/src/main/ets // 代码区 │ ├──common │ │ ├──constants │ │ │ └──CommonConstants.ets // 公共常量类 │ │ └──utils │ │ └──Logger.ets // 日志打印类 │ ├──entryability │ │ └──EntryAbility.ets // 程序入口…

【2024最新】基于springboot+vue的体质数据分析及可视化lw+ppt

作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…

MPA-SVM多变量回归预测|海洋捕食者优化算法-支持向量机|Matalb

目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、算法介绍: 四、完整程序下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译&am…

数据结构-5.6.二叉树的先,中,后序遍历

一.遍历: 二.二叉树的遍历:利用了递归操作 1.简介: 二叉树的先序遍历,中序遍历,后序遍历都是以根结点遍历顺序为准的,如先序遍历就先遍历根结点 2.实例: 例一: 例二: …