【JavaEE】——回显服务器的实现

 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:字符串转数组

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

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

相关文章

2-118 基于matlab的六面体建模和掉落仿真

基于matlab的六面体建模和掉落仿真,将对象建模为刚体来模拟将立方体扔到地面上。同时考虑地面摩擦力、刚度和阻尼所施加的力,在三个维度上跟踪平移运动和旋转运动。程序已调通,可直接运行。 下载源程序请点链接:2-118 基于matla…

基于SpringBoot“花开富贵”花园管理系统【附源码】

效果如下: 系统注册页面 系统首页界面 植物信息详细页面 后台登录界面 管理员主界面 植物分类管理界面 植物信息管理界面 园艺记录管理界面 研究背景 随着城市化进程的加快和人们生活质量的提升,越来越多的人开始追求与自然和谐共生的生活方式&#xf…

使用激光跟踪仪提升码垛机器人精度

标题1.背景 码垛机器人是一种用于工业自动化的机器人,专门设计用来将物品按照一定的顺序和结构堆叠起来,通常用于仓库、物流中心和生产线上,它们可以自动执行重复的、高强度的搬运和堆垛任务。 图1 码垛机器人 传统调整码垛机器人的方法&a…

通信工程学习:什么是DIP数据集成点

DIP:数据集成点 DIP数据集成点(Data Integration Point),简称DIP,是物联网技术(IoT)和机器到机器(M2M)通信中的一个重要组成部分。DIP在数据集成和传输过程中扮演着关键角…

【笔记】6.2 玻璃的成型

玻璃熔体的成型方法,有压制法(例如,制作水杯、烟灰缸等)、压延法(例如,制作压花玻璃等)、浇铸法(例如,制作光学玻璃、熔铸耐火材料、铸石等) 、吹制法(例如,制作瓶罐等空心玻璃)、拉制法(例如,制作窗用玻璃、玻璃管、玻璃纤维等)、离心法(例如,制作玻璃棉等)、喷吹法(例如,制作…

Ansible 工具从入门到使用

1. Ansible概述 Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主…

各类排序详解

前言 本篇博客将为大家介绍各类排序算法,大家知道,在我们生活中,排序其实是一件很重要的事,我们在网上购物,需要根据不同的需求进行排序,异或是我们在高考完报志愿时,需要看看院校的排名&#…

qt QGraphicsItem详解

一、概述 QGraphicsItem是Qt框架中图形视图框架(Graphics View Framework)的一个核心组件,它是用于表示2D图形元素的基类。 它支持的功能包括: 设置和获取图形项的位置和尺寸。控制图形项的外观,如颜色、笔刷、边框…

京东web 京东e卡绑定 第二部分分析

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 有相关问题请第一时间头像私信联系我删…

请求参数中字符串的+变成了空格

前端请求 后端接收到的结果 在URL中,某些字符(包括空格、、&、? 等)需要被编码。具体而言,在URL中,空格通常被编码为 或 %20。因此,如果你在请求参数中使用 ,它会被解释为一个空格。 如果…

2024重生之回溯数据结构与算法系列学习(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】

欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现] 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS ​ ​ ​ 专栏跑道三 ➡️HCIP;H3C-SE;CCIP——…

智能边缘计算 | 项目快速部署指南

在数字化浪潮的推动下,边缘计算与人工智能的深度融合正在成为推动智能社会发展的新动力。 边缘计算通过将数据处理和分析任务从中心服务器转移到更接近数据源的端侧,从而显著降低数据传输延迟,提高了响应速度和安全隐私性。在人工智能的加持…

python的特殊方法——魔术方法

前言 __init__(self[]) ​编辑 __call__(self [, ...]) __getitem__(self, key) __len__(self) __repr__(self) / __str__(self) __add__(self, other) __radd__(self, other) 参考文献 前言 官方定义好的,以两个下划线开头且以两个下划线结尾来命名的方法…

在QT中将Widget提升为自定义的Widget后,无法设置Widget的背景颜色问题解决方法

一、问题 在Qt中将QWidget组件提升为自定义的QWidget后,Widget设置的样式失效,例如设置背景颜色为白色失效。 二、解决方法 将已经提升的QWidget实例对象,脱离父窗体的样式,然后再重新设置自己的样式。

[ComfyUI]太赞了!阿里妈妈发布升级版 Flux 图像修复模型,更强细节生成,更高融合度以及更大分辨率支持

小伙伴们还记得我们之前介绍的阿里妈妈发布的 Flux 的 ControlNet 图像修复模型不,之前发布的是 Alpha 早期测试版本,说实话和 Flux 原生的重绘其实差距不大,有些方面甚至还是原生的效果更好。 但是现在,Alpha 的升级版本 Beta 版…

Stable Diffusion绘画 | 签名、字体、Logo设计

第1步,使用 PS(小白推荐使用 可画)准备一个 512*768 的签名、字体、Logo图片: 第2步,来到模型网站,搜索🔍关键词“电商”,找到一款喜欢的 LoRA: 第3步,选择一…

4.STM32-中断

STM32-中断 需求:红灯每两秒进行闪烁,按键key1控制绿灯亮灭 简单的程序代码无法满足要求 如何让STM32既能执行HAL_DELAY这种耗时的任务,同时又能快速响应按键按下这种突发情况呢 设置中断步骤 1.接入中断 将KEY1输入模式由原先的GPIO_In…

布隆过滤器基本原理与使用

目录 1.引言 2.基本定义 3.基本原理 4.实现方法 5.布隆过滤器的优缺点 6.哈希冲突和误判问题 7.大规模数据集Redis中布隆过滤器的性能优化 8.应用场景举例 1.引言 在互联网应用中,随着用户基数和交互数据的爆炸性增长,如何高效地处理点赞、签到、…

vue出现Component name “Politic“ should always be multi-word错误

效果 原因 组件名不能为单个单词,怕和html标签混淆 解决方法 1.选择多个单词区分 2.修改package.json里的rules规则,忽略文件命名校验

跨平台游戏的特点

跨平台游戏已成为视频游戏行业的主要趋势,这是由于对各种设备和操作系统之间无缝游戏的需求日益增长。这种方法允许玩家在多个平台(如游戏机、PC和移动设备)上享受他们最喜欢的游戏,同时保持相同的体验和进度。随着越来越多的开发…