【问题标题】:Software caused connection abort: socket write error while writing to DataOutputStream软件导致连接中止:写入 DataOutputStream 时出现套接字写入错误
【发布时间】:2019-07-27 01:36:17
【问题描述】:
 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

调试 McFee:123 - 异常 java.net.SocketException:软件导致连接中止:套接字写入错误 McaFeeC:83 - 请求标头 **** GET http://localhost:8080/appApp\filepath\ACH_IMAGE_FIVE_TWO_FIVE_zip HTTP/1.1

【问题讨论】:

  • 我们看不到“输出”的初始化,但要小心writeBytes(string),可怕的方法
  • 能否向我们提供异常的完整堆栈跟踪以及引发错误的代码?
  • DataOutputStream 此处未初始化。你也可以粘贴异常的wole堆栈跟踪吗?
  • DEBUG McFee:123 - 异常 java.net.SocketException: 软件导致连接中止:套接字写入错误 McaFeeC:83 - 请求标头 **** GET localhost:8080/appApp\filepath\ACH_IMAGE_FIVE_TWO_FIVE_zip HTTP/1.1
  • 实际上我在 zip 文件中上传了 600 张图片,然后它抛出了异常。如果我在 zip 文件中上传 500 张图片,它不会抛出任何异常。

标签: java


【解决方案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 时,这将是我的首选方式。前者会阻止 在发生错误时发送不完整的数据。注意后者 需要分块文件传输编码,否则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();
}

【讨论】:

    猜你喜欢
    • 2011-02-21
    • 2011-01-08
    • 1970-01-01
    相关资源
    最近更新 更多