gpt4 book ai didi

java - 在 Java 中出现 ConnectException 时记录源 tcp 端口?

转载 作者:可可西里 更新时间:2023-11-01 02:51:12 24 4
gpt4 key购买 nike

我正在调试从我的 Java 应用程序 (JDK 1.8.0_65) 抛出的一个奇怪的连接被拒绝错误。

我有 Wireshark 捕获,但它包括正常和错误的 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() 的情况下创建的,没有办法找出哪个源端口用于尝试建立连接。因此,为了能够报告源端口以进行调试,您需要在连接调用之前进行显式绑定(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)到端口,如果没有,将执行 bind(null) ,它应该找到一个可用的端口来绑定(bind)。

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...>

关于java - 在 Java 中出现 ConnectException 时记录源 tcp 端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36065315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com