一定の非アクティブ状態の後にファイアウォールが接続をドロップするため、既存の商用 Java アプリケーションで SO_KEEPALIVE をアクティブにする必要があります。私はソース コードを所有していないので、変更できません (ソースがあれば、 socket.setKeepAlive(true) を追加するだけでかなり簡単になります)。だから私はいくつかの選択肢を探していました:
最初に libkeepalive.so ( http://libkeepalive.sourceforge.net/ ) で作業しようとしました。これを LD_PRELOAD に入れると、telnet や nc などで機能するようですが、jrockit jvm で使用すると、この LD_PRELOAD は完全に無視され、SO_KEEPALIVE なしですべてのソケット オブジェクトがまだ作成されている
次に、すべての TCP 接続に対してデフォルトでこの SO_KEEPALIVE をアクティブにするオプションがあるかどうか、OS レベルで検索しようとしました。残念ながら、redhat 6 エンタープライズにはそのようなオプションはありませんが、freebsd (net.inet.tcp .always_keepalive)
この機能を追加するためにLinuxカーネルにパッチを当てることは、私のシステム管理者にとって大きな問題でした;)
Java コマンド ライン引数の検索に失敗しました
最後のオプション: setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(true)); を追加して、既存の JVM の java.net.PlainSocketImpl にパッチを適用します。保護された同期された void create(boolean stream) メソッドで、-Xbootclasspath/p を介して rt.jar の前に配置します
この最後のオプションはこれまでのところ機能していますが、このために JVM を変更する必要があったため、少しイライラしています。このような問題に対処するための他の/より良い方法を知っている人はいますか? すべての (Java) アプリケーションでデフォルトで SO_KEEPALIVE を有効にする別の簡単な方法がないのはなぜですか?
最後の質問: java API で serverSockets オブジェクトに keepAlive を設定できないのはなぜですか? Socket オブジェクトでのみ可能ですが、実際には serverSockets でも機能します