java用Socket简单实现银行查看余额,存款,取款的效果,相关数据存在properties文件中,不需要使用数据库

使用Socket实现银行查看余额,存款,取款用来理解Socket的使用,和如何在配置文件中存取数据有深刻的理解

相关变量

//操作存钱取钱查看钱的业务代码
BankService bankService = new BankService();
//获取与客户端连接的相关流
InputStream inputStream = socket.getInputStream();
//DataInputStream流可以直接对基本数据类型操作 使用简单  不需使数据类型转换
DataInputStream dis = new DataInputStream(inputStream);
OutputStream outputStream = socket.getOutputStream();
//DataOutputStream流可以直接对基本数据类型操作 使用简单  不需使数据类型转换
DataOutputStream dos = new DataOutputStream(outputStream);
boolean running = true;
//将running设置为true 循环接受客户端消息

查看余额

客户端实现

System.out.println("|查询金额:1|\n|存款:2|\n|取款:3|");
case "1":
cmd = "balance\n";
break;
//将命令写回服务端  服务端执行相关操作
dos.writeBytes(cmd);
System.out.println("请输入账号:");
String account = scanner.nextLine();
//将账号写回服务端  服务端执行相关操作
dos.writeBytes(account + "\n");

服务端实现

//接收客户端命令信息 用来操作下面的查看余额等操作
String cmd = dis.readLine();
System.out.println(cmd);
//输出客户端输入的账号信息
String account =dis.readLine();
System.out.println(account);
//查询余额
case "balance":
//调用bankService业务代码 得到账号余额
String balance = bankService.balance(account);
dos.writeBytes(balance + "\n");
break;

存款

客户端实现

System.out.println("|查询金额:1|\n|存款:2|\n|取款:3|");
case "2":
cmd = "deposit\n";
break;
//将命令写回服务端  服务端执行相关操作
dos.writeBytes(cmd);

System.out.println("请输入账号:");
String account = scanner.nextLine();
//将账号写回服务端  服务端执行相关操作
dos.writeBytes(account + "\n");
//如果不是查看余额 则用户有存取款金额操作
if (!"balance\n".equals(cmd)) {
System.out.println("请输入金额:");
double money = scanner.nextDouble();
dos.writeDouble(money);
//scanner.nextDouble(); 只能接受到double数 用scanner.nextLine();接收回车
scanner.nextLine();
}

服务端实现

//存款
case "deposit":
//客户端输入存入的金额
money = dis.readDouble();
//调用bankService业务代码存款并得到账号余额
System.err.println("存入金额:" + money);
String deposit = bankService.deposit(account, money);
//将存入后的新金额数写回给客户端  "DataInputStream"类读取时需要换行符 否则会阻塞  所以加上 \n
dos.writeBytes(deposit + "\n");
break;

取款和上面存款操作差不多 主要看下当取款金额大于当前金额时的业务代码

Service
//取款

	public String withdraw(String account,double money){
		//先取出当前账户的金额 
		String accountMoney = oprateProperties.getKeyValue(account);
		//若当前取款金额大于账户金额 返回ERROR取钱失败
		double withdrawMoney = Double.parseDouble(accountMoney) - money;
		if(withdrawMoney < 0){
			return "ERROR";//取款金额大于账号总金额
		}
		//当最后一个参数为flase表示取钱  将money的钱取入account账户中 存入properties文件中
		oprateProperties.setKeyValue(account, money+"", false);
		return oprateProperties.getKeyValue(account);
	}


//从properties中设置账户和金额  flag为true时对原始金额做存款操作  flag为false时对原始金额做取款操作
	public void setKeyValue(String key,String value,boolean flag){
		//进行存取款操作
		String val = getKeyValue(key);
		//账户里的金额
		double previousMoney = Double.parseDouble(val);
		//要操作的金额数
		double changedMoney = Double.parseDouble(value);
		//操作后的金额
		String currentMoney;
		//flag 为true 存款
		if(flag){
			currentMoney = (previousMoney + changedMoney) + "";
		}else{
			//false 取款
			currentMoney = (previousMoney - changedMoney) + "";
		}
		//将账号的金额数改变
		properties.setProperty(key, currentMoney);
		//将数据保存到properties文件中
		storeProperties();
	}

完整实现代码:

需要手动创建一个空的bank.properties文件
//要存入的文件名 放在src下

public final static String FILE_NAME = "bank.properties";

可以改成自己定义的名字

操作properties的工具类OprateProperties
OprateProperties.java

package com.jt.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class OprateProperties {
	
	//要存入的文件名  放在src下
	public final static String FILE_NAME = "bank.properties";
	private Properties properties = new Properties();
	//获取此文件的输入流  对properties进行加载操作
	private InputStream in = OprateProperties.class.getClassLoader().getResourceAsStream(FILE_NAME);
	
	//得到当前账号key的金额 key为账号 account
	public String getKeyValue(String key){
		loadProperties();
		if(properties.containsKey(key)){
			return properties.getProperty(key);
		}
		//如果没有当前账号则返回 0 设置值时 新建此用户
		return "0";
	}
	//从properties中设置账户和金额  flag为true时对原始金额做存款操作  flag为false时对原始金额做取款操作
	public void setKeyValue(String key,String value,boolean flag){
		//进行存取款操作
		String val = getKeyValue(key);
		//账户里的金额
		double previousMoney = Double.parseDouble(val);
		//要操作的金额数
		double changedMoney = Double.parseDouble(value);
		//操作后的金额
		String currentMoney;
		//flag 为true 存款
		if(flag){
			currentMoney = (previousMoney + changedMoney) + "";
		}else{
			//false 取款
			currentMoney = (previousMoney - changedMoney) + "";
		}
		//将账号的金额数改变
		properties.setProperty(key, currentMoney);
		//将数据保存到properties文件中
		storeProperties();
	}
	//加载配置文件里面的账号金额信息
	public void loadProperties(){
		try {
			properties.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//将数据保存到properties文件中
	public void storeProperties(){
		try {
			//获取src下文件的绝对路径
			String filePath = System.getProperty("user.dir")+"\\src\\" + FILE_NAME;
			FileOutputStream fos = new FileOutputStream(new File(filePath));
			System.out.println(filePath);
			//第二个参数 是注解  #bank server
			properties.store(fos, "bank server");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

完成Bank的业务代码BankService
BankService.java

package com.jt.socket.bank;

import com.jt.utils.OprateProperties;

public class BankService {
	//oprateProperties相当于数据库操作的dao层
	private OprateProperties oprateProperties = new OprateProperties();
	public String balance(String account){
		//获得account账号的money值
		return oprateProperties.getKeyValue(account);
	}
	//存款
	public String deposit(String account,double money){
		//将钱存入properties文件中  当最后一个参数为true表示存钱  将money的钱存入account账户中
		oprateProperties.setKeyValue(account, money+"", true);
		//返回存好前后的金额
		return oprateProperties.getKeyValue(account);
	}
	//取款
	public String withdraw(String account,double money){
		//先取出当前账户的金额 
		String accountMoney = oprateProperties.getKeyValue(account);
		//若当前取款金额大于账户金额 返回ERROR取钱失败
		double withdrawMoney = Double.parseDouble(accountMoney) - money;
		if(withdrawMoney < 0){
			return "ERROR";//取款金额大于账号总金额
		}
		//当最后一个参数为flase表示取钱  将money的钱取入account账户中 存入properties文件中
		oprateProperties.setKeyValue(account, money+"", false);
		return oprateProperties.getKeyValue(account);
	}
}

BankServer服务端代码
BankServer.java

package com.jt.socket.bank;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BankServer {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws Exception {
		//操作存钱取钱查看钱的业务代码
		BankService bankService = new BankService();
		
		//Bank服务端创建 和 与客户端建立连接
		ServerSocket server = new ServerSocket(9999);
		Socket socket = server.accept();
		System.out.println("客户端连接成功");
		
		//获取与客户端连接的相关流
		InputStream inputStream = socket.getInputStream();
		//DataInputStream流可以直接对基本数据类型操作 使用简单  不需使数据类型转换
		DataInputStream dis = new DataInputStream(inputStream);
		OutputStream outputStream = socket.getOutputStream();
		//DataOutputStream流可以直接对基本数据类型操作 使用简单  不需使数据类型转换
		DataOutputStream dos = new DataOutputStream(outputStream);
		
		boolean running = true;
		//将running设置为true 循环接受客户端消息
		while (running) {
			//接收客户端命令信息 用来操作下面的查看余额等操作
			String cmd = dis.readLine();
			System.out.println(cmd);
			//输出客户端输入的账号信息
			String account =dis.readLine();
			System.out.println(account);
			
			//用来操作 存款和取款操作
			double money = 0;
			//判断是什么cmd命令
			switch (cmd) {
			//查询余额
			case "balance":
				//调用bankService业务代码 得到账号余额
				String balance = bankService.balance(account);
				dos.writeBytes(balance + "\n");
				break;
			//存款
			case "deposit":
				//客户端输入存入的金额
				money = dis.readDouble();
				//调用bankService业务代码存款并得到账号余额
				System.err.println("存入金额:" + money);
				String deposit = bankService.deposit(account, money);
				//将存入后的新金额数写回给客户端  "DataInputStream"类读取时需要换行符 否则会阻塞  所以加上 \n
				dos.writeBytes(deposit + "\n");
				break;
			//取款
			case "withdraw":
				//客户端输入存入的金额
				money = dis.readDouble();
				//调用bankService业务代码取款并得到账号余额
				System.err.println("取出金额:" + money);
				String withdraw = bankService.withdraw(account, money);
				//将存入后的新金额数写回给客户端  "DataInputStream"类读取时需要换行符 否则会阻塞  所以加上 \n
				dos.writeBytes(withdraw + "\n");
				break;
			}
		}
		server.close();
	}
}

客户端BankClient代码
BankClient.java

package com.jt.socket.bank;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class BankClient {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) throws Exception {
		// 客户端与服务端建立连接
		Socket socket = new Socket("127.0.0.1", 9999);
		// 创建一个控制台输入对象
		Scanner scanner = new Scanner(System.in);

		// 获取与客户端连接的相关流
		InputStream inputStream = socket.getInputStream();
		// DataInputStream流可以直接对基本数据类型操作 使用简单 不需使数据类型转换
		DataInputStream dis = new DataInputStream(inputStream);
		OutputStream outputStream = socket.getOutputStream();
		// DataOutputStream流可以直接对基本数据类型操作 使用简单 不需使数据类型转换
		DataOutputStream dos = new DataOutputStream(outputStream);
		
		boolean running = true;
		//将running设置为true 循环接受服务端消息
		while (running) {
			//提示用户操作
			System.out.println("_______________________________");
			System.out.println("|查询金额:1|\n|存款:2|\n|取款:3|");
			System.out.println("_______________________________");
			String commend = scanner.nextLine();
			String cmd = null;
			//用户输入命令
			switch (commend) {
			case "1":
				cmd = "balance\n";
				break;
			case "2":
				cmd = "deposit\n";
				break;
			case "3":
				cmd = "withdraw\n";
				break;
			}
			//将命令写回服务端  服务端执行相关操作
			dos.writeBytes(cmd);
			
			System.out.println("请输入账号:");
			String account = scanner.nextLine();
			//将账号写回服务端  服务端执行相关操作
			dos.writeBytes(account + "\n");
			//如果不是查看余额 则用户有存取款金额操作
			if (!"balance\n".equals(cmd)) {
				System.out.println("请输入金额:");
				double money = scanner.nextDouble();
				dos.writeDouble(money);
				//scanner.nextDouble(); 只能接受到double数 用scanner.nextLine();接收回车
				scanner.nextLine();
			}
			//读取服务端执行相关命令后返回给用户的金额
			String currentMoney = dis.readLine();
			System.out.println(account + "当前金额:" + currentMoney);
			
		}
		socket.close();
		scanner.close();
	}

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值