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

J2ME M-Mail 更新日誌:多賬號、SSL、短信轉發與 HTTP flush 死徹底解決

     編輯:J2ME

新增功能

  1. 多賬號支持:系統支持最多 3 個郵箱賬號並行管理。
  2. POP3/SMTP over SSL:支援加密郵件收發,提升安全性。
  3. 閱讀郵件時一鍵轉發至短信:內容摘要通過 SMS 分享。

疑難雜症:HTTP OutputStream.flush() 導致阻塞

現象

在聯想 S9 等部分手機上,HTTP 通訊寫入數據後調用 out.flush(),線程永久阻塞,無異常拋出,初以為是撥號模塊故障。

根因分析 (來源: Java2me.org 論壇)

flush() 觸發 HTTP 1.1 的 Chunked Transfer Encoding (分塊傳輸)。若服務器/代理為 HTTP 1.0 或不支持分塊傳輸,會導致連接掛起。

「調用 flush() 使用了 HTTP 1.1 的特性,允許分小塊發送數據。若使用 HTTP 1.0 服務器/代理,分塊傳輸會導致問題。」

解決方案

  1. 小數據量請求:用 close() 替代 flush()。close() 會發送 Content-Length 頭並一次性寫完,不使用分塊編碼。
  2. 大數據量請求:在內存中緩衝完整請求體,單次 write() + close() 發送,避免中間 flush()。

代碼修正示例

// 錯誤寫法 (可能阻塞)
OutputStream out = httpConn.openOutputStream();
out.write(requestData);
out.flush(); // 觸發分塊編碼,風險!
out.close();

// 正確寫法 1: 小數據直接 close
OutputStream out = httpConn.openOutputStream();
out.write(requestData);
out.close(); // 無分塊,安全

// 正確寫法 2: 大數據緩衝後一次性發送
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// ... 寫入大量數據到 baos ...
byte[] fullData = baos.toByteArray();
httpConn.setRequestProperty("Content-Length", String.valueOf(fullData.length));
OutputStream out = httpConn.openOutputStream();
out.write(fullData);
out.close();

經驗總結

  • J2ME HTTP 實現差異極大,**flush() 在移動網絡環境下是高風險操作**。
  • 除非確知服務端支持 Chunked Encoding 且中間無 HTTP 1.0 代理,**默認使用 close() 結束寫入**。
  • 大數據上傳採用「內存緩衝 → 設置 Content-Length → 一次性 write/close」模式。

版本信息

M-Mail 版本更新包含上述修復,建議所有用戶升級以避免 HTTP 通訊阻塞問題。

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