1. 序章

このクイックチュートリアルでは、例を使用してSocketExceptionの原因を学習します。

もちろん、例外の処理方法についても説明します。

2. SocketExceptionの原因

SocketExceptionの最も一般的な原因は、閉じたソケット接続との間でデータを読み書きすることです。別の原因は、ソケットバッファー内のすべてのデータを読み取る前に接続を閉じることです。

いくつかの一般的な根本的な理由を詳しく見てみましょう。

2.1. 遅いネットワーク

不十分なネットワーク接続が根本的な問題である可能性があります。 より高いソケット接続タイムアウトを設定すると、低速接続のSocketExceptionの発生率が低下する可能性があります。

socket.setSoTimeout(30000); // timeout set to 30,000 ms

2.2. ファイアウォールの介入

ネットワークファイアウォールはソケット接続を閉じることができます。 ファイアウォールにアクセスできる場合は、ファイアウォールをオフにして、問題が解決するかどうかを確認できます。

それ以外の場合は、Wiresharkなどのネットワーク監視ツールを使用してファイアウォールのアクティビティを確認できます。

2.3. 長いアイドル接続

アイドル状態の接続は、(リソースを節約するために)もう一方の端で忘れられる可能性があります。 長時間接続を使用する必要がある場合は、アイドル状態を防ぐためにハートビートメッセージを送信できます。

2.4. アプリケーションエラー

最後になりましたが、 SocketException は、コードの間違いやバグが原因で発生する可能性があります。

これを示すために、ポート6699でサーバーを起動してみましょう。

SocketServer server = new SocketServer();
server.start(6699);

サーバーが起動すると、クライアントからのメッセージを待ちます。

serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String msg = in.readLine();

取得したら、応答して接続を閉じます:

out.println("hi");
in.close();
out.close();
clientSocket.close();
serverSocket.close();

したがって、クライアントがサーバーに接続して「hi」を送信するとします。

SocketClient client = new SocketClient();
client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi");

ここまでは順調ですね。

ただし、クライアントが別のメッセージを送信した場合:

client.sendMessage("hi again");

接続が中止された後、クライアントはサーバーに「hiagain」を送信するため、SocketExceptionが発生します。

3. SocketExceptionの処理

SocketExceptionの処理は非常に簡単で簡単です。 他のチェックされた例外と同様に、それをスローするか、try-catchブロックで囲む必要があります。

この例で例外を処理しましょう。

try {
    client.sendMessage("hi");
    client.sendMessage("hi again");
} catch (SocketException e) {
    client.stopConnection();
}

ここでは、 例外が発生した後、クライアント接続を閉じました。 接続がすでに閉じられているため、再試行は機能しません。 代わりに、新しい接続を開始する必要があります。

client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi again");

4. 結論

この記事では、SocketExceptionの原因とその処理方法について説明しました。

いつものように、コードはGithubから入手できます。