简体   繁体   中英

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;

}

While writing String to writeBytes it is throwing error like java.net.SocketException: Software caused connection abort: socket write error java.lang.ArrayIndexOutOfBoundsException: 512

DEBUG McaFee:123 - Exception java.net.SocketException: Software caused connection abort: socket write error McaFeeC:83 - Request Header **** GET http://localhost:8080/appApp \\filepath\\ACH_IMAGE_FIVE_TWO_FIVE_zip HTTP/1.1

Your question misses the part how you initialize the DataOutputStream but the error message lets me assume that you open an HttpUrlConnection to a server and call getOutputStream on it.

Your question also misses the part where you create the String that is passed to the send method and if you indeed create a ZIP-file using a String to contain that binary data will most likely lead to corrupted data at some point.

My answer is based on the following code I assume is working here:

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"));

What can happen here is that the HttpUrlConnection is opening the connection to the server and then the connections sits idle until you've finished creating the ZIP. If it takes too long the server will run into a timeout and will close the connection. Trying to send data to a closed socket lead to the error message you've seen.

The reason why it works up to a given number of files is that the generation is then quick enough to stay within the timeout.

There are different solutions for this:

  • Create the ZIP before you open the connection
  • Create the ZIP "on the fiy" by sending the data during creation

Which one is better depends. If you can be sure that there will be no error while creating the ZIP it would be my preferred way. The former would prevent the sending of incomplete data in case of an error. Note that the latter needs Chunked File-Transfer-Encoding, otherwise the HttpUrlConnection will buffer everything to evaluate the value for the Content-Length header that would otherwise be needed. So if you transfer data to a server that is not supporting this, you end up with variant 1.

Here is an example for the latter:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM