1. ホーム
  2. java

[解決済み] java.net.SocketException: 接続が相手によってリセットされました: ソケット書き込みエラー ファイル提供時

2022-02-02 14:41:01

質問

ソケットを使用した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

皆さん、回答ありがとうございました。皆さんの回答を読んで、問題はエラーが発生したときのSocketにあることが分かりました。以下は私の間違ったコードでした。

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

解決方法は?

TCPソケットが閉じようとしているのに、あなたのコードがまだ通知されていない可能性があります。

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

基本的には、クライアントによって接続が閉じられました。 あなたはすでに throws IOExceptionSocketException が拡張します。 IOException . これで問題なく動作しています。 ただ IOException というのも、これはAPIの正常な部分だからです。

編集部: この RST パケットは、存在しない、または閉じられたソケットでパケットを受信したときに発生します。 アプリケーションに差支えはありません。 実装によっては reset の状態が固まることがあり closed が正式に発生することはありません。