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

Java TCP 並發圖片上傳實戰:多線程與檔案覆蓋解決方案

     編輯:Java 綜合教學

Java TCP 並發圖片上傳實戰

本文完整實現基於 TCP 協定的並發圖片上傳系統,涵蓋客戶端/伺服端架構、多線程併發處理、檔案命名衝突解決、命令列參數校驗等工程級細節。

系統架構設計

  • 客戶端:讀取本地圖片 → Socket 輸出流發送 → 關閉輸出流通知完成 → 讀取伺服端回饋 → 關閉連線。
  • 伺服端:ServerSocket.accept() 循環監聽 → 每個連線啟動獨立執行緒處理 → 接收資料寫入檔案 → 回傳結果。

核心難點與解決方案

1. 併發處理:每連線一執行緒

// 伺服端主循環
while (true) {
    Socket socket = serverSocket.accept();
    new Thread(new UploadPicServerThread(socket)).start(); // 核心:分派執行緒
}

// 執行緒任務類
class UploadPicServerThread implements Runnable {
    private final Socket socket;
    public UploadPicServerThread(Socket s) { this.socket = s; }
    @Override public void run() { /* 處理單個客戶端上傳邏輯 */ }
}

2. 檔案覆蓋問題:IP + 序號命名

String ip = socket.getInetAddress().getHostAddress(); // 獲取客戶端 IP
int fileNum = 1;
File file = new File(ip + ".png");
while (file.exists()) { // 衝突則遞增序號
    file = new File(ip + "(" + (fileNum++) + ").png");
}
// 例如:192.168.1.100.png → 192.168.1.100(1).png → 192.168.1.100(2).png

3. 客戶端參數校驗:主函數嚴格檢查

// 必須且僅有一個參數
if (args.length != 1) { System.out.println("請選擇一個文件"); return; }
File file = new File(args[0]);
// 必須存在、是檔案、副檔名 .png、大小 ≤ 1MB
if (!file.exists() || !file.isFile() ||
    !file.getName().endsWith(".png") || file.length() > 1024*1024) {
    System.out.println("請選擇小於1M的png文件"); return;
}

關鍵代碼片段:雙向通訊協定

// 客戶端發送
OutputStream out = socket.getOutputStream();
FileInputStream fis = new FileInputStream(localFile);
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) out.write(buffer, 0, len);
socket.shutdownOutput(); // 關鍵:告知伺服端「發送完畢」

// 接收回饋
InputStream in = socket.getInputStream();
byte[] resp = new byte[1024];
len = in.read(resp);
System.out.println(new String(resp, 0, len));

// 伺服端接收並回饋
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
while ((len = is.read(buffer)) != -1) fos.write(buffer, 0, len);
OutputStream os = socket.getOutputStream();
os.write("上傳成功!".getBytes());

工程化優化建議

  1. 執行緒池替換 new Thread:使用 ExecutorService 限制併發數,防止連線風暴耗盡資源。
  2. 協定框架化:引入長度前綴、序列化框架(Protobuf/JSON)支援斷點續傳、多檔案傳輸。
  3. 安全強化:SSL/TLS 加密傳輸、檔案型別驗證(Magic Number)、上傳目錄隔離執行權限。
  4. 監控與日誌:記錄上傳耗時、失敗原因、客戶端 IP 統計。

此實戰案例展示了 Java 網絡編程從「能跑通」到「可生產」的關鍵躍升點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved