CardServer
package com.shrimpking.t4;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2024/10/22 10:47
*/
public class CardServer extends JFrame
{
private JTextArea taInfo; //文本框,提示
private ServerSocket server; //服务器套接字
private Socket socket; //套接字
public CardServer(){
this.setTitle("某某大学校园一卡通服务器端");
this.setBounds(100,100,400,400);
taInfo = new JTextArea();
taInfo.setEnabled(false); //不可编辑
taInfo.setLineWrap(true); //可换行
JScrollPane scrollPane = new JScrollPane(taInfo
,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); //滚动条面板
this.setLayout(new BorderLayout()); //设置窗体边框布局模式
this.getContentPane().add(scrollPane, BorderLayout.CENTER); //居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //窗体关闭
this.setResizable(false);
this.setVisible(true);
createSocket(); //创建套接字
}
public void createSocket(){
try
{
server = new ServerSocket(2987); //创建服务器套接字对象
taInfo.append("等待新客户连接...\n");
while (true){
socket = server.accept(); //有客户连接,创建套接字对象
taInfo.append("客户端连接成功。" + socket + "\n");
ServerThread st = new ServerThread(socket);
st.start(); //开启线程
}
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args)
{
CardServer frame = new CardServer();
}
}
ServerThread
package com.shrimpking.t4;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2024/10/22 11:00
*/
public class ServerThread extends Thread
{
private Socket socket; //套接字
private DataInputStream dis; //数据输入流
private PrintWriter pw; //输出流
private Connection conn; //数据库连接
public ServerThread(Socket socket){
this.socket = socket;
}
//打开数据库链接
private Connection openDB(){
try
{
String url = "jdbc:mysql://localhost:3306/test"; //链接地址
Class.forName("com.mysql.jdbc.Driver"); //加载数据库驱动
this.conn = DriverManager.getConnection(url,"root","mysql123"); //创建链接对象
return conn;
}catch (Exception e){
System.out.println("数据库连接出错");
e.printStackTrace();
return null; //失败,返回null
}
}
//创建网络连接,
private boolean connectNet(){
try
{
System.out.println("服务器网络链接开始了...");
dis = new DataInputStream(socket.getInputStream()); //通过套接字输入流生成,数据输入流
pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); //输出流
return true;
}catch (Exception e){
System.out.println("网络连接错误");
e.printStackTrace();
return false;
}
}
@Override
public void run()
{
String flag = "NO"; //未成功
String s;
if (connectNet()){
//初始化流对象成功
System.out.println("服务器网络连接成功...");
while (true){
try
{
if ((s = dis.readLine()) != null){
System.out.println(s); //输出读取的信息,用于核对校验程序的有效性
if (s.startsWith("001"))
{
//登录 001%用户名%密码
String[] str = s.split("%");
String user = str[1]; //用户名
String password = str[2]; //密码
System.out.println("user:" + user + " pass:" + password); //输出,提示
String s2; //数据库存的用户名
String s3; //数据库存的密码
try
{
Statement stmt = this.openDB().createStatement(); //打开数据库,
ResultSet rs = stmt.executeQuery("select * from bp_account"); //返回结果集
while (rs.next())
{
//如果结果集有数据
if ((rs.getString("username").equals(user)) && (rs.getString("password")).equals(password))
{
//判断数据集中是否有正确的
s2 = rs.getString("username");
s3 = rs.getString("password");
System.out.println(s2 + " * " + s3);
flag = "OK"; //标识,读取成功
}
}
pw.println(flag); //向客户端发送成功标识
pw.flush(); //清空缓存,立即发送
System.out.println("flag is " + flag); //输出,提示
}
catch (SQLException e)
{
System.out.println("查询用户和密码出现异常");
}
}else if (s.startsWith("002")){
//查询余额 002%用户名
String[] str = s.split("%");
String user = str[1]; //用户名
double money = 0; //余额
try
{
Statement stmt = this.openDB().createStatement();
ResultSet rs = stmt.executeQuery("select * from bp_account"); //返回结果集
while (rs.next()){
//如果结果集有数据时
if (rs.getString("username").equals(user)){
money = rs.getDouble("money"); //读取余额
System.out.println("当前账户余额:" + money); //输出,提示
}
}
pw.println("002%" + money); //向客户端发送
pw.flush(); //清空缓存,立即发送
}catch (SQLException e){
System.out.println("查询账户余额出现异常");
}
}else if (s.startsWith("003")){
//修改密码 003%用户名%新密码
String[] str = s.split("%");
String user = str[1]; //用户名
String newPwd = str[2]; //新密码
int i = 0; //默认,修改密码不成功
try
{
Statement stmt = this.openDB().createStatement();
String sql = String.format("update bp_account set password='%s' where username='%s'",newPwd,user);
i = stmt.executeUpdate(sql); //执行修改
}catch (SQLException e){
System.out.println("修改密码出现异常");
}
if (i == 1){
//修改数据库成功
pw.println("003%OK"); //向客户端发送,修改成功
pw.flush(); //清空缓存,立即发送
}else{
pw.println("003%NO");
pw.flush();
}
}else if (s.startsWith("004")){
//存钱接收到的是004%用户名%金额
String[] str = s.split("%");
String user = str[1]; //用户名
double money = Double.parseDouble(str[2]); //存钱金额
int i = 1; //默认,成功
try
{
Statement stmt = this.openDB().createStatement();
String sql = String.format("update bp_account set money=money + '%f' where username='%s'",money,user);
i = stmt.executeUpdate(sql); //执行
System.out.println("服务器执行数据库存钱操作" + i);
}catch (SQLException e){
System.out.println("修改余额出现异常");
}
if (i == 1){
//修改成功
pw.println("004%OK"); //向客户端发送
pw.flush(); //立即
}else{
pw.println("004%NO");
pw.flush();
}
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
CardLogin
package com.shrimpking.t4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2024/10/22 13:09
*/
public class CardLogin extends JFrame implements ActionListener
{
private JTextField txtUser; //用户名
private JPasswordField txtPass; //密码
private PrintWriter pw; //输出流
private BufferedReader br; //输入流
private Socket socket; //套接字
public CardLogin(){
//
this.setSize(250,125); //窗体尺寸
this.setTitle("某某大学校园一卡通登录");
this.setResizable(false); //不可最大化
//布置输入面板
JPanel panelInput = new JPanel();
panelInput.setLayout(new GridLayout(2,2)); //2行2列
//创建组件
JLabel labelUser = new JLabel("账号(10位):"); //标签 用户名
JLabel labelPass = new JLabel("密码:"); //标签 密码
txtUser = new JTextField(); //用户名
txtPass = new JPasswordField(); //密码
panelInput.add(labelUser);
panelInput.add(txtUser);
panelInput.add(labelPass);
panelInput.add(txtPass);
//
JPanel panelBtn = new JPanel();
panelBtn.setLayout(new FlowLayout()); //流式布局
JButton btnLogin = new JButton("登录");
JButton btnCancel = new JButton("取消");
btnLogin.addActionListener(this); //按钮事件
btnCancel.addActionListener(this);
panelBtn.add(btnLogin);
panelBtn.add(btnCancel);
//布置窗体
this.setLayout(new BorderLayout()); //边界布局
this.add(panelInput,BorderLayout.CENTER); //居中
this.add(panelBtn,BorderLayout.SOUTH); //底部
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗体,结束程序
this.setLocationRelativeTo(null); //屏幕居中
this.setVisible(true); //可见性
createSocket();
}
private void createSocket(){
try
{
socket = new Socket("127.0.0.1",2987); //创建套接字对象
br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //输入流
pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); //输出流
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("登录")){
String user = txtUser.getText(); //获取用户名
String password = txtPass.getText(); //获取密码
if (user.equals("")) return;
if (password.equals("")) return;
String s;
pw.println("001%" + user + "%" + password); //向服务器发送001%用户名%密码
pw.flush(); //清空缓存,立即发送
try
{
s = br.readLine(); //从输入流读取
System.out.println(s);
if (s.startsWith("OK")){
//
System.out.println("客户端登录接收到 " + s);
UserMes userMes = new UserMes(user,password);
CardClient client = new CardClient(userMes,socket);
this.setVisible(false);
System.out.println("弹出主界面");
}else{
JOptionPane.showMessageDialog(this,"请输入正确的用户名和密码");
txtUser.setText("");
txtPass.setText("");
}
}catch (HeadlessException | IOException ex){
ex.printStackTrace();
}
}else if (e.getActionCommand().equals("取消")){
txtUser.setText("");
txtPass.setText("");
}
}
public static void main(String[] args)
{
new CardLogin();
}
}
CardClient
package com.shrimpking.t4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2024/10/22 14:46
*/
public class CardClient extends JFrame implements ActionListener
{
private JLabel label1; //标签,提示
private JLabel label2; //标签,提示
private JButton btnSelect; //查询
private JButton btnGet; //存钱
private JButton btnPass; //修改密码
private JButton btnOk; //确定
private JButton btnExit; //退出
private JButton[] buttons; //数字按钮
private JPanel panel1; //面板,上部分
private JPanel panel2; //面板,下部分
private JPanel panel3; //面板,下部分左侧
private JPanel panel4; //面板,下部分右侧
private CardClientThread cardClientThread; //客户端线程
private PrintWriter pw; //输出流
private Socket clientSocket; //套接字
private String flag; //标识
private UserMes um; //用户实体
public CardClient(UserMes um,Socket socket){
this.um = um; //
this.clientSocket = socket;
this.setSize(400,400); //窗体尺寸
this.setTitle("某某大学校园一卡通登录");
this.setResizable(false); //不可最大化
label1 = new JLabel("请选择");
label2 = new JLabel("");
btnSelect = new JButton("查询");
btnGet = new JButton("存钱");
btnPass = new JButton("修改密码");
btnOk = new JButton("确定");
btnExit = new JButton("退出");
btnSelect.addActionListener(this); //按钮事件
btnGet.addActionListener(this);
btnPass.addActionListener(this);
btnOk.addActionListener(this);
btnExit.addActionListener(this);
buttons = new JButton[12]; //数字按钮
for (int i = 0; i < buttons.length - 2; i++)
{
buttons[i] = new JButton("" + i);
buttons[i].addActionListener(new NumberButton()); //数字按钮事件
}
buttons[10] = new JButton("*");
buttons[10].addActionListener(this); //
buttons[11] = new JButton("#");
buttons[11].addActionListener(this);
panel1 = new JPanel();
panel2 = new JPanel();
panel3 = new JPanel();
panel4 = new JPanel();
panel1.setLayout(new GridLayout(3,1)); //3行1列
panel1.add(label1);
panel1.add(label2);
panel3.setLayout(new GridLayout(4,3)); //4行3列
for (int i = 0; i < buttons.length; i++)
{
panel3.add(buttons[i]);
}
panel4.setLayout(new GridLayout(5,1,7,7)); //5行1列
panel4.add(btnSelect);
panel4.add(btnGet);
panel4.add(btnPass);
panel4.add(btnOk);
panel4.add(btnExit);
panel2.setLayout(new GridLayout(1,2)); //1行2列
panel2.add(panel3); //面板,下部分左侧
panel2.add(panel4); //面板,下部分右侧
this.setLayout(new GridLayout(2,1)); //2行1列
this.add(panel1); //上部分
this.add(panel2); //下部分
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗体,结束程序
this.setLocationRelativeTo(null); //屏幕居中
this.setVisible(true);
createSocket(); //创建套接字
}
private void createSocket(){
try
{
//输出流,自动刷新缓存
pw = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()),true);
}catch (IOException e){
e.printStackTrace();
}
cardClientThread = new CardClientThread(clientSocket); //客户端线程
cardClientThread.start(); //开启线程
}
//内部类
class NumberButton implements ActionListener{
@Override
public void actionPerformed(ActionEvent e)
{
label2.setText((label2.getText() + e.getActionCommand().trim())); //存钱的金额
}
}
@Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == btnSelect){
//查询按钮
pw.println("002%" + um.getUsername()); //向服务器发送002%用户名,查询
pw.flush(); //清空缓存,立即发送
}else if (e.getSource() == btnGet){
//存钱
label1.setText("请输入您的存款数额");
label2.setText("");
btnSelect.setEnabled(false); //查询按钮不可用
btnPass.setEnabled(false); //修改密码不可用
}else if (e.getSource() == btnPass){
//修改密码
label1.setText("请输入您的四位新密码:");
label2.setText("");
btnSelect.setEnabled(false); //查询不可用
btnGet.setEnabled(false); //存钱不可用
}else if (e.getSource() == btnOk){
//确定
if (btnPass.isEnabled() == false && btnGet.isEnabled() == true){
//存钱时,客户端向服务器发送004%用户名%存钱金额
pw.println("004%" + um.getUsername() + "%" + label2.getText());
pw.flush();
System.out.println("存钱后的确定");
btnSelect.setEnabled(true); //查询可用
btnPass.setEnabled(true); //修改密码可用
label2.setText("");
}else if (btnPass.isEnabled() == true && btnGet.isEnabled() == false){
//修改密码时,客户端向服务器发送003%用户名%新密码
if (label2.getText().equals("")) {
label1.setText("请输入4位密码...");
return;
}
pw.println("003%" + um.getUsername() + "%" + label2.getText());
pw.flush();
System.out.println("修改密码后的确定");
btnSelect.setEnabled(true);
btnGet.setEnabled(true);
label2.setText("");
}
}else if (e.getSource() == btnExit){
System.exit(0); //退出系统
}
}
public void put(){
label1.setText("您的余额为:");
label2.setText("元");
}
class CardClientThread extends Thread
{
private Socket socket; //套接字
private PrintWriter pw; //输出流
private BufferedReader br; //字符缓冲输入流
public CardClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run()
{
try
{
br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //通过套接字获取流
}catch (IOException e){
System.out.println("客户端主界面创建socket出现异常");
}
//
while (true){
String info;
try
{
info = br.readLine().trim(); //读取服务器的消息
System.out.println("客户端主界面接收到的信息" + info);
if (info.startsWith("002")){
//查询余额
label2.setText(String.format("当前用户查询余额:%s",info.split("%")[1]));
}else if (info.startsWith("003")){
//修改密码
label1.setText("");
if (info.split("%")[1].equals("OK")){
label2.setText("密码修改成功");
}else if (info.split("%")[1].equals("NO")){
label2.setText("密码修改失败,请重新修改");
}
}else if (info.startsWith("004")){
//存钱确定
label1.setText("");
if (info.split("%")[1].equals("Ok")){
label2.setText("存钱成功");
}else if (info.split("%")[1].equals("NO")){
label2.setText("存钱失败");
}
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
}
UserMes
package com.shrimpking.t4;
/**
* Created by IntelliJ IDEA.
*
* @Author : Shrimpking
* @create 2024/10/22 16:11
*/
public class UserMes
{
private String username;
private String password;
public UserMes(String username,String password){
this.username = username;
this.password = password;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
}
SQL
drop table if exists bp_account;
create table bp_account(
id int not null auto_increment primary key comment '主键',
username varchar(10) not null unique comment '账号',
password varchar(6) not null comment '密码',
money NUMERIC(8,2) comment '金额'
) comment '账户表';
insert into bp_account values(null,'user1','1234',100);
insert into bp_account values(null,'user2','1234',200);
insert into bp_account values(null,'user3','1234',300);