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

PHP Socket 傳輸大文件至 Java 接收端:分塊發送與多線程接收完整實現

     編輯:PHP 相關知識

架構概覽

  • 客戶端:PHP fsockopen 建立 TCP 連接,分塊讀取文件並發送
  • 服務端:Java ServerSocket 監聽,每連接啟動一線程 WebThread 接收寫入磁盤

PHP 客戶端核心代碼

$fp = fsockopen("127.0.0.1", 1024, $errno, $errstr, 10);
$filename = '2012_07_23.zip';
fwrite($fp, $filename . "\r\n"); // 首行傳文件名

$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));

$data_size = 1024 * 1024; // 1MB 分塊
$data_count = ceil(strlen($contents) / $data_size);
for ($i = 0; $i < $data_count; $i++) {
    $data = substr($contents, $i * $data_size, $data_size);
    fwrite($fp, $data);
}
fclose($fp);

關鍵點:

  1. 首行發送文件名,換行符 \r\n 配合 Java readLine()
  2. 大文件分塊(1MB)發送,避免記憶體溢出
  3. 發送完畢關閉連接,觸發服務端 read() 返回 -1 結束循環

Java 服務端實現

主類 MyApp:監聽與分發

ServerSocket server = new ServerSocket(1024);
for (;;) {
    Socket client = server.accept();
    new WebThread(client, i++).start(); // 每連接一線程
}

線程類 WebThread:接收寫入

DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
String filename = in.readLine(); // 讀取文件名
String savePath = "E:\\" + filename;
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(savePath)));

byte[] buf = new byte[8192];
int read;
while ((read = in.read(buf)) != -1) {
    out.write(buf, 0, read);
}
out.flush(); out.close(); in.close();

關鍵點:

  • 雙重 BufferedOutputStream 為筆誤,一層即可
  • read(buf) 返回實際讀取字節數,-1 表示流結束
  • 寫入時必須指定 offset=0, len=read,避免殘留舊數據

生產環境優化建議

  1. 協議增強:增加文件大小頭、MD5 校驗、斷點續傳標識
  2. 緩衝區調優:根據網絡 MTU 調整 buf 大小(如 64KB)
  3. 異常處理:捕獲 IOException 並記錄日志,確保資源 finally 關閉
  4. 並發控制:使用線程池替代無限創建線程,防止 OOM
  5. 安全性:校驗文件名防止目錄遍歷攻擊(../../etc/passwd)

總結

PHP + Java Socket 跨語言文件傳輸,核心在於約定協議(首行文件名 + 二進制流)與流式分塊處理。示例代碼雖簡陋,但演示了完整鏈路。生產環境需在協議層、可靠性、安全性、併發模型上全面強化。

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