Javaアプリケーション(JDK 1.8.0_65)からスローされた奇妙な接続拒否エラーをデバッグしています。
Wiresharkキャプチャを取得しましたが、通常のTCPセグメントとエラーのTCPセグメントの両方が含まれており、どちらがどちらであるかを区別する方法がありません。
Javaがスローされたときに送信元ポート番号をログアウトさせることができるかどうか知りたいConnectException
ので、それを使用して検索できます。AspectJのようなツールを使用してこれを行うことはできますか?
参考までに、スタックトレースは次のとおりです。
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method) ~[na:1.8.0_65]
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79) ~[na:1.8.0_65]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_65]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_65]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_65]
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.8.0_65]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_65]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_65]
...
クライアントソケットが明示的に作成されていない場合、bind()
接続の確立に使用された送信元ポートを見つける方法はありません。したがって、デバッグの目的で送信元ポートについてレポートできるようにするには、接続呼び出しの前に明示的なバインドを行う必要があります。クライアントコードのソースにアクセスできる場合は、同様の方法で更新できます。
SocketAddress target = new InetSocketAddress(host, port);
int localPort = -1;
try (Socket socket = new Socket()) {
socket.bind(null);
localPort = socket.getLocalPort();
socket.connect(target, timeout);
} catch (IOException e) {
throw new IOException(
String.format("couldn't connect to %s from port %d", target, localPort), e);
}
クライアントのソースコードを変更できない場合は、次の側面を使用してクライアントコードを織り込むことができます。へのメソッド呼び出しをインターセプトすることで機能しSocket.connect(...)
、ソケットがすでにポートにバインドされているかどうかを判断し、バインドされていない場合は、を実行してbind(null)
、バインドに使用できるポートを見つける必要があります。
import java.io.IOException;
import java.net.Socket;
import java.net.SocketAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public aspect SocketExceptionLoggerAspect {
private static final Logger logger = LoggerFactory
.getLogger(SocketExceptionLoggerAspect.class);
pointcut callToSocketConnect(SocketAddress target):
call(void Socket+.connect(..)) && args(target, ..);
void around(SocketAddress target, Socket socket) :
callToSocketConnect(target) && target(socket) {
int localPort = socket.getLocalPort();
if (localPort == -1) {
try {
socket.bind(null);
localPort = socket.getLocalPort();
} catch (IOException e) {
}
}
try {
proceed(target, socket);
} catch (IOException e) {
logger.error(String.format("couldn't connect to %s from port %d", target,
localPort), e);
}
}
}
出力例:
SocketExceptionLoggerAspect - couldn't connect to stackoverflow.com/104.16.33.249:123 from port 49840 <stack trace...>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加