web-dev-qa-db-ja.com

java.net.SocketException:ピアによる接続のリセット:ファイルを提供する際のソケット書き込みエラー

ソケットを使用してHTTPサーバーを実装しようとしています。クライアント(ブラウザなど)がディレクトリを要求すると、サーバーは使用可能なファイルのリストを表示します。クライアントがファイルを要求しているときに問題が発生します。次のエラーが表示されます。

_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)
_

スタックトレースは、問題がwriteFile()メソッドに起因していることを示しています。

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

しかし、何が悪いのかわかりません。手伝って頂けますか?

[〜#〜] edit [〜#〜]

回答ありがとうございます。私はあなたの答えを読んだ後、私は問題がエラーが発生したときにソケットであることを理解しました。ここに私の間違ったコードがありました:

_// 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
    }
}
_

そして、私の新しいコードは次のようになりました。

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

TCPソケットが「閉じている」可能性があり、コードがまだ通知されていない可能性があります。

これがライフサイクルのアニメーションです。 http://tcp.cs.st-andrews.ac.uk/index.shtml?page=connection_lifecycle

基本的に、接続はクライアントによって閉じられました。既にthrows IOExceptionおよびSocketExceptionIOExceptionを拡張します。これはうまく機能しています。 IOExceptionはAPIの通常の部分であるため、適切に処理する必要があります。

編集:RSTパケットは、存在しないか閉じられたソケットでパケットを受信したときに発生します。アプリケーションに違いはありません。実装によっては、reset状態が続く場合があり、closedは公式には発生しません。

13
bond

この問題は通常、ピアによってすでに閉じられている接続への書き込みが原因で発生します。この場合、たとえば、ユーザーがダウンロードをキャンセルしたことを示している可能性があります。

1
user207421