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.rhkb.cn/news/315683.html

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

相关文章

小型架构实验模拟

一 实验需求 二 实验环境 22 机器&#xff1a; 做nginx 反向代理 做静态资源服务器 装 nginx keepalived filebeat 44机器&#xff1a; 做22 机器的备胎 装nginx keepalived 99机器&#xff1a;做mysql的主 装mysqld 装node 装filebeat 77机器&#xff1a;做mysq…

Git零基础

Git工作流程图 操作指令 分支 、 指令总结 远程仓库

ubuntu安装Anaconda安装及conda使用

一. 安装anaconda3详细教程 1、下载镜像 清华大学开源软件镜像站下载地址&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下拉到最低端选择Linux&#xff0c;选择最新版&#xff08;32/64位&#xff09;下载。这里我下载的是版本Anaconda3-4.3.30-Linux…

python应用-socket网络编程(1)

目录 1 先简单回顾下客户端和服务端通信的知识 2 服务端常用函数 3 客户端常用函数 4 服务端和客户端都用的函数 5 示例介绍客户端和服务端通信过程 6 建立服务端套接制 7 创建服务端函数socket.create_server() 8 创建客户端套接字 9 客户端连接函数socket.create_co…

Asp .Net Core 系列:国际化多语言配置

文章目录 概述术语 本地化器IStringLocalizer在服务类中使用本地化 IStringLocalizerFactoryIHtmlLocalizerIViewLocalizer 资源文件区域性回退 配置 CultureProvider内置的 RequestCultureProvider实现自定义 RequestCultureProvider使用 Json 资源文件 设计原理IStringLocali…

MATLAB语音信号分析与合成——MATLAB语音信号分析学习资料汇总(图书、代码和视频)

教科书&#xff1a;MATLAB语音信号分析与合成&#xff08;第2版&#xff09; 链接&#xff08;含配套源代码&#xff09;&#xff1a;https://pan.baidu.com/s/1pXMPD_9TRpJmubPGaRKANw?pwd32rf 提取码&#xff1a;32rf 基础入门视频&#xff1a; 视频链接&#xff1a; 清…

Eclipse C++ 无法debug 问题

环境&#xff1a; ubuntu20.04 Eclipse CDT&#xff08;x86_64) 工程&#xff0c;使用的是默认的CMake Project 现象&#xff1a; 1. 使用Eclipse&#xff0c; 加了断点后&#xff0c;debug 无法停在断点&#xff1b;step over 执行后是从main 直接执行到exit &#xff…

七彩虹(Colorful)隐星P16 2023款笔记本电脑原装出厂Win11系统镜像下载 带建Recovery一键还原功能

七彩虹原厂Windows预装OEM专用系统&#xff0c;恢复出厂开箱状态一模一样 适用型号&#xff1a;隐星P16 23 链接&#xff1a;https://pan.baidu.com/s/1Ig5MQMiC8k4VSuCOZRQHUw?pwdak5l 提取码&#xff1a;ak5l 原厂W11系统自带所有驱动、出厂时自带的主题与专用壁纸、系…

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测

分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测 目录 分类预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现POA-BP鹈鹕算法优化BP神经网络多特征分类预测&#xff08;Matlab实…

31 OpenCV 距离变换和分水岭算法

文章目录 距离变换分水岭算法distanceTransform 距离变换watershed 分水岭算法示例 距离变换 分水岭算法 distanceTransform 距离变换 void cv::distanceTransform (InputArray src,OutputArray dst,int distanceType,int maskSize,int dstType CV_32F) src:输入图像&#xf…

Android 学习 鸿蒙HarmonyOS 4.0 第二天(项目结构认识)

项目结构认识 和 了解&#xff1a; 工程目录下的结构如下&#xff1a; 首先能看到有两个.开头的文件&#xff0c;分别是.hvigor 和 .idea。这两个文件夹都是与构建有关系的&#xff0c; 如果你开发过安卓app&#xff0c;构建完会生成一个apk安装包&#xff0c;鸿蒙则是生成hap…

maya blendshape

目录 shape编辑器 maya创建blendshape python 脚本 添加形变动画 查看顶点个数 shape编辑器 打开方式&#xff1a; 窗口-动画编辑器-形变编辑器 maya创建blendshape python 脚本 import maya.cmds as cmds# 创建基础网格 - 球体 baseMesh cmds.polySphere(name"bas…

一文讲解Android车载系统camera架构 - EVS

Android的camera开发中&#xff0c;使用最多的是camera2 以及现在Google主推的cameraX 架构&#xff0c;而这两个架构主要针对的是手机移动端上camera的流程。 而今天介绍的EVS(Exterior View System)架构是不同于camera2上的手机架构&#xff0c;针对Automotive的版本&#x…

ETL中双流合并和多流合并的区别

一、ETL工具 ETLCloud数据集成平台集实时数据集成和离线数据集成以及API发布为一体的数据集成平台。与其他开源数据集成工具相比&#xff0c;采用轻量化架构、具有更快的部署速度、更快的数据传输速度、更低的运维成本&#xff0c;同时支持多租户的团队协作能力&#xff0c;能…

opencv_17_翻转与旋转

一、图像翻转 1&#xff09;void flip_test(Mat& image); 2&#xff09;void ColorInvert::flip_test(Mat& image) { Mat dst; //flip(image, dst, 0); //上下翻转 flip(image, dst, 1); //左右翻转 // flip(image, dst, -1); //180度翻转 imsho…

JAVA读取从WPS在Excel中嵌入的图片资源

读取从WPS在Excel中嵌入的图片资源 引言 许多数据文件中可能包含嵌入式图片&#xff0c;这些图片对于数据分析和可视化非常重要。然而&#xff0c;从 WPS 在 Excel 中读取这些图片可能会有一些技术挑战。在本文中&#xff0c;我将展示如何从 WPS Excel 文件中读取嵌入的图片&am…

Jmeter Beanshell 设置全局变量

//获取token import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONArray; import java.util.*; import org.apache.jmeter.util.JMeterUtils; //获取可上机机器 String response prev.getResponseDataAsString(); JSONObject responseObect JSONObjec…

【CANoe示例分析】TCP Chat(CAPL) with TLS encription

1、工程路径 C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 15.3.89\Ethernet\Simulation\TLSSimChat 在CANoe软件上也可以打开此工程:File|Help|Sample Configurations|Ethernet - Simulation of Ethernet ECUs|Basic AUTOSAR Adaptive(SOA) 2、示例目…

秋招后端开发面试题 - JVM底层原理

目录 JVM底层原理前言面试题Java 对象的创建过程&#xff1f;什么是指针碰撞&#xff1f;什么是空闲列表&#xff1f;/ 内存分配的两种方式&#xff1f;JVM 里 new 对象时&#xff0c;堆会发生抢占吗&#xff1f;JVM 是怎么设计来保证线程安全的&#xff1f;/ 内存分配并发问题…

tokio多任务绑定cpu(绑核)

tokio 是 rust 生态中流行的异步运行时框架。在实际生产中我们如果希望 tokio 应用程序与特定的 cpu core 绑定该怎么处理呢&#xff1f; 首先我们先写一段简单的多任务程序。 use tokio; use tokio::runtime; use core_affinity;fn tokio_sample() {let rt runtime::Builde…