繁体   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