软件导致连接异常终止:写入DataOutputStream时套接字写入错误

时间:2019-03-05 14:38:24

标签: java

 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

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

1 个答案:

答案 0 :(得分:0)

您的问题错过了如何初始化DataOutputStream的部分,但是错误消息让我假设您打开了服务器的HttpUrlConnection并在服务器上调用getOutputStream

您的问题还错过了创建String并传递到send方法的部分,以及是否确实使用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();
}