Pertanyaan java.net.SocketException: Koneksi ulang oleh rekan: socket write error Ketika melayani file


Saya mencoba menerapkan Server HTTP menggunakan Soket. Jika Klien (Misalnya browser) meminta direktori, server akan menampilkan daftar file yang tersedia. Masalah muncul ketika klien meminta file. Saya mendapatkan kesalahan berikut:

java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at cf.charly1811.java.web.RequestHandler.writeFile(RequestHandler.java:152)
at cf.charly1811.java.web.RequestHandler.processRequest(RequestHandler.java:139)
at cf.charly1811.java.web.RequestHandler.handleRequest(RequestHandler.java:110)
at cf.charly1811.java.web.RequestHandler.run(RequestHandler.java:86)
at java.lang.Thread.run(Thread.java:745)

The stacktrace menunjukkan bahwa masalahnya berasal dari writeFile() metode:

private void writeFile(File request) throws IOException 
{
    InputStream byteReader = new BufferedInputStream(new FileInputStream(request));
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = byteReader.read(buffer)) != -1) 
    {
        outputStream.write(buffer, 0, bytesRead);
    }
    byteReader.close();
}

Tapi aku tidak tahu apa yang salah. Bisakah kamu membantuku?

EDIT

Terimakasih semuanya untuk jawaban Anda. Setelah saya membaca jawaban Anda, saya mengerti bahwa masalahnya adalah Socket ketika terjadi kesalahan. Ini kode saya yang salah:

// Method to process a single request
handleRequest() throw IOException
{
    // process here
    // if the client request a file
    writeFile();
    // close socket when the request is processed
}

// The method is called
public run()
{
    try{
        // If an error occurs the try/catch won't be called because it is implemented outside the loop. So when an IOException occurs, the loop just stop and exit the program
        while(true)
        {
            handleRequest();
        }
    }
    catch(IOException e) {
        // Handle exception here
    }
}

Dan kode baru saya terlihat seperti ini:

// Method to process a single request
handleRequest()
{
   try {
        // process here
        // if the client request a file
        writeFile();
        // close socket when the request is processed
    }
    // If this exception occurs the catch() method will be called
    catch(IOException e)
    {
        // handle exception here
    }
}

// The method is called
public run()
{
    while(true)
        {
            handleRequest();
        }
    }
}

9
2017-09-01 19:11


asal


Jawaban:


Hal ini dimungkinkan untuk soket TCP menjadi "penutupan" dan kode Anda belum diberitahu.

Berikut ini animasi untuk siklus kehidupan. http://tcp.cs.st-andrews.ac.uk/index.shtml?page=connection_lifecycle

Pada dasarnya, koneksi ditutup oleh klien. Anda sudah punya throws IOException dan SocketException meluas IOException. Ini berfungsi dengan baik. Anda hanya perlu menangani dengan benar IOException karena itu adalah bagian normal dari api.

EDIT: The RST paket terjadi ketika paket diterima pada soket yang tidak ada atau ditutup. Tidak ada perbedaan dengan aplikasi Anda. Tergantung pada implementasinya reset negara dapat menempel dan closed tidak akan pernah secara resmi terjadi.


11
2017-09-02 00:31



Masalah ini biasanya disebabkan oleh penulisan ke koneksi yang sudah ditutup oleh rekan. Dalam hal ini bisa menunjukkan bahwa pengguna membatalkan pengunduhan misalnya.


1
2017-09-02 00:00