首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Socket 多執行緒銀行伺服器實戰:從協議設計到交易處理

     編輯:Java 相關知識

本文完整實作一個基於 TCP Socket 的多執行緒銀行後台系統,涵蓋伺服器啟動、客戶端請求分發、交易協議解析、資料庫存取 (JDBC/MySQL)、查詢/存款/提款/轉帳四大核心業務,適合學習網路程式設計與分層架構。

系統架構概覽

Client (ATM 前端)
    │ TCP Socket (port 8848)
    ▼
BankServer (Main Thread) ──accept()──▶ ServerThread (Worker Thread per Client)
    │                                      │
    │                                      ▼
    │                              Transaction (Business Logic)
    │                                      │
    │                                      ▼
    │                              MySQL Database (JDBC)
    │                              Tables: Account, Record

核心類別職責

通訊協議設計 (文字型)

格式:交易類型-參數1-參數2-...,以 - 分隔,行尾換行符結束。

類別職責關鍵方法
BankServer啟動 ServerSocket、監聽連線、分發執行緒main()
ServerThread處理單一客戶端會話、讀取請求、回送回應run()
Transaction封裝業務邏輯、解析協議、資料庫操作、事務控制check(), credit(), debit(), virement()

關鍵程式碼片段

伺服器主類別

public class BankServer {
    private static int PORT = 8848;
    
    public static void main(String[] args) throws IOException {
        if (args.length > 0) PORT = Integer.parseInt(args[0]);
        
        try (ServerSocket server = new ServerSocket(PORT)) {
            System.out.println("Bank server started on port " + PORT);
            while (true) {
                Socket client = server.accept();
                new ServerThread(client).start(); // 每連線一執行緒
            }
        }
    }
}

交易處理核心 (以轉帳為例)

private String virement(String request) {
    // 解析:virement-帳號-密碼-目標帳號-金額
    String[] parts = request.split("-", 5);
    String fromAcc = parts[1];
    String pwd = parts[2];
    String toAcc = parts[3];
    BigDecimal amount = new BigDecimal(parts[4]);
    
    // 檢查餘額
    String sqlBalance = "SELECT Balance FROM Account WHERE AccountNo=? AND Password=?";
    try (PreparedStatement ps = conn.prepareStatement(sqlBalance)) {
        ps.setString(1, fromAcc);
        ps.setString(2, pwd);
        ResultSet rs = ps.executeQuery();
        if (!rs.next() || amount.compareTo(rs.getBigDecimal("Balance")) > 0) {
            return "-Wrong password or haven't enough money";
        }
    }
    
    // 檢查目標帳號存在
    String sqlExist = "SELECT 1 FROM Account WHERE AccountNo=?";
    try (PreparedStatement ps = conn.prepareStatement(sqlExist)) {
        ps.setString(1, toAcc);
        if (!ps.executeQuery().next()) {
            return "-Otherside account not exist";
        }
    }
    
    // 扣款 + 入款 + 記錄 (需事務)
    conn.setAutoCommit(false);
    try {
        updateBalance(fromAcc, amount.negate());
        updateBalance(toAcc, amount);
        recordTransaction(fromAcc, amount.negate(), toAcc);
        recordTransaction(toAcc, amount, fromAcc);
        conn.commit();
        return "+Transaction complete";
    } catch (SQLException e) {
        conn.rollback();
        throw e;
    } finally {
        conn.setAutoCommit(true);
    }
}

資料庫結構 (MySQL)

CREATE TABLE Account (
    AccountNo VARCHAR(20) PRIMARY KEY,
    Password VARCHAR(20) NOT NULL,
    Balance DECIMAL(15,2) DEFAULT 0
);

CREATE TABLE Record (
    Id BIGINT AUTO_INCREMENT PRIMARY KEY,
    AccountNo VARCHAR(20),
    TransDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    TransMoney DECIMAL(15,2),
    TransNo VARCHAR(20)  -- 轉帳對方帳號
);

設定檔 (config.data)

com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/bank?user=root&password=your_password&useUnicode=true&characterEncoding=UTF-8

安全性與健壯性增強建議

交易類型請求格式回應格式
查詢餘額check-帳號-密碼+Your account balance is: 1000 / -Wrong account or password
存款credit-帳號-金額+Transaction complete / -Error
提款debit-帳號-密碼-金額+Transaction complete / -Wrong password or haven't enough money
轉帳virement-帳號-密碼-目標帳號-金額+Transaction complete / -Otherside account not exist

結語

這個銀行伺服器範例展示了 Socket 程式設計、多執行緒模型、JDBC 事務處理、協議解析的核心技術。實際生產系統需引入安全框架、連線池、監控、日誌、叢集等企業級基礎設施,建議採用 Netty、Spring Boot、gRPC 等成熟框架加速開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題改善方案
明文傳輸密碼SSL/TLS 加密通道 (JSSE) 或至少 SHA-256 雜湊後傳輸
SQL 注入風險全面使用 PreparedStatement 參數化查詢
執行緒無限制執行緒池 (ExecutorService) 限制並發數
資料庫連線洩漏連線池 (HikariCP/Druid) + try-with-resources
無心跳/閒置斷線SO_TIMEOUT / 應用層心跳機制
協議無版本/擴展性採用 JSON/Protobuf + 版本欄位