簡體   English   中英

軟件導致連接異常終止:寫入DataOutputStream時套接字寫入錯誤

[英]Software caused connection abort: socket write error while writing to DataOutputStream

 private DataOutputStream output = null;
 private int send(String str) throws IOException {
  int response = 0;
  output.writeBytes(str);
  output.flush();
  return response;

}

將String寫入writeBytes時會引發類似java.net.SocketException的錯誤:軟件導致連接中止:套接字寫入錯誤java.lang.ArrayIndexOutOfBoundsException:512

調試McaFee:123-異常java.net.SocketException:軟件導致連接中止:套接字寫入錯誤McaFeeC:83-請求標頭**** GET http:// localhost:8080 / appApp \\ filepath \\ ACH_IMAGE_FIVE_TWO_FIVE_zip HTTP / 1.1

您的問題錯過了如何初始化DataOutputStream的部分,但是錯誤消息讓我假設您打開了到服務器的HttpUrlConnection並在其上調用getOutputStream

您的問題還錯過了創建傳遞給send方法的String的部分,如果您確實使用String包含二進制數據來創建ZIP文件,則很可能會在某些時候導致數據損壞。

我的答案基於我認為在此處工作的以下代碼:

HttpUrlConnection conn = new URL("www.example.com/upload").openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
String dataToSend = createDataToSend();
dos.writeBytes(dataToSend.getBytes("8859_1"));

此處可能發生的情況是HttpUrlConnection正在打開與服務器的連接,然后連接處於空閑狀態,直到完成創建ZIP為止。 如果花費的時間太長,則服務器將超時並關閉連接。 嘗試將數據發送到封閉的套接字會導致您看到錯誤消息。

它可以處理給定數量的文件的原因是,生成速度足夠快,可以保持在超時范圍內。

有不同的解決方案:

  • 打開連接之前創建ZIP
  • 通過在創建過程中發送數據來創建“隨時隨地”的ZIP

哪個更好取決於。 如果可以確定在創建ZIP時沒有任何錯誤,那將是我的首選方式。 前者可以防止發生錯誤時發送不完整的數據。 請注意,后者需要Chunked File-Transfer-Encoding,否則HttpUrlConnection將緩沖所有內容以評估原本需要的Content-Length標頭的值。 因此,如果將數據傳輸到不支持此功能的服務器,則最終會出現變體1。

這是后者的示例:

private int doSend(File baseDir) throws IOException {
    File[] files = baseDir.listFiles();
    if (files.length == 0) {
        return -1;
    }
    HttpURLConnection conn = (HttpURLConnection) new URL("www.example.com/upload").openConnection();
    conn.setDoInput(true);
    conn.setDoOutput(true);
    conn.setChunkedStreamingMode(250);
    OutputStream os = conn.getOutputStream();
    ZipOutputStream zos = new ZipOutputStream(os);
    for (int i = 0; i < files.length; i++) {
        ZipEntry ze = new ZipEntry(files[i].getName());
        zos.putNextEntry(ze);
        try (FileInputStream fis = new FileInputStream(files[i])) {
            byte[] buf = new byte[4096];
            int read;
            while ((read = fis.read(buf)) != -1) {
                zos.write(buf, 0, read);
            }
        }
    }
    zos.flush();
    return conn.getResponseCode();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM