java案例-服务端与客户端(传输对象)

需求

在这里插入图片描述

代码

  • SysUser 用户类
  • Operation 操作类
  • Client 客户端
  • Server 服务端
  • ServerReaderThread 服务端线程类

SysUser 用户类

  • 需要实现Serializable 方便序列化,传输对象
public class SysUser implements Serializable {private String username;private String password;public SysUser() {}public SysUser(String username, String password) {this.username = username;this.password = password;}public String getUsername() {return this.username;}public String getPassword() {return this.password;}public void setUsername(String username) {this.username = username;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "SysUser{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}
}

操作类

操作方法和被操作的用户

public class Operation implements Serializable {private String operation;private SysUser sysUser;public Operation() {}public Operation(String operation, SysUser sysUser) {this.operation = operation;this.sysUser = sysUser;}public String getOperation() {return this.operation;}public SysUser getSysUser() {return this.sysUser;}public void setOperation(String operation) {this.operation = operation;}public void setSysUser(SysUser sysUser) {this.sysUser = sysUser;}@Overridepublic String toString() {return "Operation{" +"operation='" + operation + '\'' +", sysUser=" + sysUser +'}';}
}

客户端

  • 本例是一个长连接:一直挂在服务器端,那么服务器端的读取线程中就必须要有一个while 循环 不断读取此长连接的内容
  • 如果不使用本例的方法,而是每次都创建新的socket 连接服务器,那么读取线程中就必须要有一个while 循环就是非必要的,因为每次连接只会发送一次,等待服务器端响应之后,需要关闭此socket,这就是短连接
// 该类是一个客户端类
public class Client {private static Scanner scanner = new Scanner(System.in);public static void main(String[] args) throws IOException {start();}// 该方法是一个启动方法public static void start() throws IOException {Scanner scanner = new Scanner(System.in);Socket socket = new Socket("127.0.0.1",8888);// 此处加死循环 是为了让客户端一直运行while (true){System.out.println("请输入你要进行的操作");System.out.println("1.注册");System.out.println("2.登录");System.out.println("3.退出");String i = scanner.next();switch (i){case "1":System.out.println("注册");register(socket);break;case "2":System.out.println("登录");login(socket);break;case "3":System.out.println("退出");socket.close();break;default:System.out.println("输入错误,请重新输入");}}}// 该方法是一个注册方法public static void register(Socket socket) throws IOException {System.out.println("请输入用户名");String username = scanner.next();System.out.println("请输入密码");String password = scanner.next();SysUser sysUser = new SysUser(username,password);Operation operation = new Operation("register",sysUser);// 获取输出流requestAndRespond(socket, operation);}private static void requestAndRespond(Socket socket, Operation operation) throws IOException {OutputStream outputStream = socket.getOutputStream();// 封装输出流为对象输出流ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);// 写出对象objectOutputStream.writeObject(operation);objectOutputStream.flush();// 不要关闭流 否则会关闭socket//objectOutputStream.close();// 获取响应InputStream inputStream = socket.getInputStream();DataInputStream dataInputStream = new DataInputStream(inputStream);String response = dataInputStream.readUTF();System.out.println(response);}// 该方法是一个登录方法public static void login(Socket socket) throws IOException {System.out.println("请输入用户名");String username = scanner.next();System.out.println("请输入密码");String password = scanner.next();SysUser sysUser = new SysUser(username,password);Operation operation = new Operation("login",sysUser);// 获取输出流requestAndRespond(socket, operation);}
}

服务器端

// 该类是一个服务端类
public class Server {// 模拟数据库public static final File file = new File("test999.txt");public static ServerSocket serverSocket;//  创建线程池public static final ExecutorService pool =  new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());static {try {serverSocket = new ServerSocket(8888);} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {start();}// 该方法是一个启动方法public static void start() throws IOException {System.out.println("服务端启动");listen();}public static void listen() throws IOException {System.out.println("监听中");// 此处加死循环 是为了让服务器已知监听有没有客户端连接while (true){// 获取客户端的socketSocket socket = serverSocket.accept();// 使用线程池执行线程pool.execute(new ServerReaderThread(socket));}}// 该方法是一个注册方法public static void register(SysUser sysUser,Socket socket) throws IOException, ClassNotFoundException {System.out.println("注册");// 获取数据库中的所有用户FileInputStream fileInputStream = new FileInputStream(file);if (fileInputStream.available() > 0) {ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);ArrayList<SysUser> sysUsers = (ArrayList<SysUser>) objectInputStream.readObject();for (SysUser user : sysUsers) {if (user.getUsername().equals(sysUser.getUsername())) {System.out.println("用户名已存在");OutputStream outputStream = socket.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeUTF("用户名已存在");dataOutputStream.flush();
//                    dataOutputStream.close();return;}}}// 注册用户// 将用户写入数据库 追加模式FileOutputStream fileOutputStream = new FileOutputStream(file,true);ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);ArrayList<SysUser> sysUsersRegister = new ArrayList<>();sysUsersRegister.add(sysUser);objectOutputStream.writeObject(sysUsersRegister);System.out.println("注册成功");System.out.println(sysUser);OutputStream outputStream = socket.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeUTF("注册成功");dataOutputStream.flush();
//        dataOutputStream.close();}// 该方法是一个登录方法public static void login(SysUser sysUser,Socket socket) throws IOException, ClassNotFoundException {System.out.println("登录");// 获取数据库中的所有用户FileInputStream fileInputStream = new FileInputStream(file);if (fileInputStream.available() > 0) {ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);ArrayList<SysUser> sysUsers = (ArrayList<SysUser>) objectInputStream.readObject();for (SysUser user : sysUsers) {if (user.getUsername().equals(sysUser.getUsername())&&user.getPassword().equals(sysUser.getPassword())) {System.out.println("登录成功");System.out.println(sysUser);OutputStream outputStream = socket.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeUTF("登录成功");dataOutputStream.flush();
//                    dataOutputStream.close();}else {System.out.println("用户名或密码错误");OutputStream outputStream = socket.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeUTF("用户名或密码错误");dataOutputStream.flush();
//                    dataOutputStream.close();}}}else {System.out.println("数据库中没有用户");OutputStream outputStream = socket.getOutputStream();DataOutputStream dataOutputStream = new DataOutputStream(outputStream);dataOutputStream.writeUTF("数据库中没有用户");dataOutputStream.flush();
//            dataOutputStream.close();}}
}

服务器端读取类

  • 本例是一个长连接:一直挂在服务器端,那么服务器端的读取线程中就必须要有一个while 循环 不断读取此长连接的内容
  • 如果不使用本例的方法,而是每次都创建新的socket 连接服务器,那么读取线程中就必须要有一个while 循环就是非必要的,因为每次连接只会发送一次,等待服务器端响应之后,需要关闭此socket,这就是短连接
ServerReaderThread extends Thread {private Socket socket;public ServerReaderThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {// 最开始这个地方没有死循环,导致客户端只能发送一次请求// 这个地方加入死循环 是为了即使是一个request也能一直获得用户的输入// 这个地方如果不加入死循环,那么应该建立短连接// 也就是说,客户端发送一个请求,都会建立一个新的socket,服务端处理完这个请求之后,返回给客户端结果,客户端处理完结果之后,关闭socketwhile(true){// 获取输入流InputStream inputStream = socket.getInputStream();// 封装输入流为对象输入流ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);// 读取对象Operation operation = (Operation) objectInputStream.readObject();// 获取操作String operation1 = operation.getOperation();// 获取用户SysUser sysUser = operation.getSysUser();System.out.println("线程方法");switch (operation1) {case "register":register(sysUser,socket);break;case "login":login(sysUser,socket);break;default:break;}}} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}
}

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

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

相关文章

kerberos-hive-dbeaver问题总结

一、kerberos安装windows客户端 1、官方下载地址 http://web.mit.edu/kerberos/dist/ 2、环境变量配置 下载msi安装包&#xff0c;无需重启计算机&#xff0c;调整环境变量在jdk的前面&#xff0c;尽量靠前&#xff0c;因为jdk也带了kinit、klist等命令 C:\Program Files\…

【Node.js工程师养成计划】之原生node开发web服务器

一、使用node创建http服务器 var http require(http);// 获取到服务器实例对象 var server http.createServer() server.listen(8080, function() {console.log(http://127.0.0.1:8080); })server.on(request, function(req, res){console.log(request);res.write(6666666688…

如何利用 GPT 自我提高写作能力

GPT革命&#xff1a;如何用AI技术重新定义写作 介绍 在我们的数字时代&#xff0c;了解自我提高写作的必要性至关重要。 随着 GPT 的兴起&#xff0c;我们正在见证书写的变革时代。 这篇扩展文章深入探讨了 GPT 如何显着提高写作技能。 拥抱未来&#xff1a; 人工智能时代的写…

Maven介绍 主要包括Maven的基本介绍,作用,以及对应的Maven模型,可以对Maven有一个基本的了解

1、Maven介绍 1.1 什么是Maven Maven是Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 官网&#xff1a;https://maven.apache.org/ Apache 软件基金会&#xff0c;成立于1999年7月&#xff0c;是目前世界上最大的最受欢迎的开源软件基金会&…

Elasticsearch实现hotel索引库自动补全、拼音搜索功能

Elasticsearch实现hotel索引库自动补全、拼音搜索功能 在这里边我们有两个字段需要用拼音分词器&#xff0c;一个name字段&#xff0c;一个all字段。 然后我们还需要去实现自动补全&#xff0c;而自动补全对应的字段必须使用completion类型。目前我们酒店里面所有的字段都采用的…

【SpringBoot】00 Maven配置及创建项目

一、Maven配置 1、下载Maven 进入官网下载&#xff1a;Maven – Welcome to Apache MavenMaven – Download Apache Maven 本文以最新版为例&#xff0c;可按需选择版本 Maven – Welcome to Apache Maven 2、解压下载好的安装包 将安装包解压到自己设置的空文件夹中 3、…

AI视频教程下载:构建一个ChatGPT股票配对交易机器人

ChatGPT及其后续版本GPT-4已经开始改变世界。人们对新机会感到兴奋&#xff0c;同时对我们社会可能受到的影响感到恐惧。这门课程结合了两个主题&#xff1a;AI和财务&#xff08;算法交易&#xff09;。 你将会学到的&#xff1a; 使用ChatGPT构建一个Python配对交易机器人 …

(Linux)Centos7.*版本安装配置Java环境、Tomcat、Nginx并打包部署SSM框架web系统

一、准备软件与安装包 (一)、必须的软件 1、点击下载Xshell 2、点击下载FileZilla (二)、准备安装包 1、点击下载JDK1.8Linux版本 2、点击下载Nginx 3、点击下载Tomcat 二、关于FileZilla软件的使用说明 (一)、FileZilla软件的打开和说明 (二)、配置服务器地址去连…

理解ROS2的动作

​ 1. 创建一个动作 目标&#xff1a; 在ROS 2软件包中定义一个动作。 1.1 新建包 设置一个 workspace 并创建一个名为 action_tutorials_interfaces 的包&#xff1a; mkdir -p ros2_ws/src #you can reuse existing workspace with this naming convention cd ros2_ws/s…

NLP发展及其详解

一、RNN(循环神经网络) 在这里附上一个很好的笔记 零基础入门深度学习(5) - 循环神经网络 RNN(循环神经网络)的结构特点在于其循环单元的设计,这种设计允许网络在处理序列数据时保持对之前信息的记忆。下面详细解释RNN的结构: 循环单元:RNN的循环单元是网络的核心,它…

基于Springboot的爱心商城系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的爱心商城系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

[BT]BUUCTF刷题第25天(4.28)

第25天&#xff08;共3题&#xff09; Web [CISCN 2019 初赛]Love Math 打开网站就是一段泄露的源代码&#xff1a; <?php error_reporting(0); //听说你很喜欢数学&#xff0c;不知道你是否爱它胜过爱flag if(!isset($_GET[c])){show_source(__FILE__); }else{//例子 c…

【LeetCode刷题记录】简单篇-70-爬楼梯

【题目描述】 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 【测试用例】 示例1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1.1阶 1阶…

C语言-------实现贪吃蛇小游戏

目录 一、预备知识 1.1 Win32 API介绍 Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外&#xff0c; 它同时也是一个很大的服务中心&#xff0c;调用这个服务中心的各种服务&#xff08;每一种服务就是一个函数&#xff09;&#xff0c;可以帮应用程…

PyVista 3D数据可视化 Python 库 简介

Pyvista是一个用于科学可视化和分析的Python库 &#xff1b;我认为它适合做一些网格数据的处理&#xff1b; 它封装了VTK&#xff08;Visualization Toolkit&#xff09;之上&#xff0c;提供了一些高级接口&#xff0c; 3D数据可视化变得更加简单和易用。 1.安装 pyvista&…

SpringMVC进阶(自定义拦截器以及异常处理)

文章目录 1.自定义拦截器1.基本介绍1.说明2.自定义拦截器的三个方法3.流程图 2.快速入门1.Myinterceptor01.java2.FurnHandler.java3.springDispatcherServlet-servlet.xml配置拦截器4.单元测试 3.拦截特定路径1.拦截指定路径2.通配符配置路径 4.细节说明5.多个拦截器1.执行流程…

LeetCode 150. 逆波兰表达式求值

LeetCode 150. 逆波兰表达式求值 1、题目 题目链接&#xff1a;150. 逆波兰表达式求值 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 ‘’、‘-’、…

如何基于Zookeeper实现注册中心模型?

在分布式系统中&#xff0c;通常会存在几十个甚至上百个服务&#xff0c;开发人员可能甚至都无法明确系统中到底有哪些服务正在运行。另一方面&#xff0c;我们很难同时确保所有服务都不出现问题&#xff0c;也很难保证当前的服务部署方式不做调整和优化。由于自动扩容、服务重…

tableau如何传参数到MySQL数据库

1、打开tableau连接本地MySQL-》新建自定义sql-》创建参数 2、新建一个简单的工作表-》把维度拖拽到行显示结果-》右键显示参数 3、参数传递到数据库sql写法 select * from yonghu where yonghu.姓名 like concat(%,<参数.姓名>,%)select * FROMabadata4WHERE abadata4…

基于STM32单片机的汽车胎压、速度及状态监测系统设计与实现

基于STM32单片机的汽车胎压、速度及状态监测系统设计与实现 摘要&#xff1a; 随着汽车电子技术的快速发展&#xff0c;车辆状态实时监控系统的需求日益增长。本文设计并实现了一种基于STM32单片机的汽车胎压、速度及状态监测系统。该系统能够实时监测汽车的胎压、速度以及其他…