gpt4 book ai didi

java - 奇怪的 InetAddress.isReachable() 问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:16:41 26 4
gpt4 key购买 nike

我的工作是为零售环境的网络摄像头开发软件。我的团队正在开发的软件之一是一个网络服务器,它可以检索由相机本身(它有自己的嵌入式网络服务器)以 HTML 格式生成并存储在相机上的各种报告。然后,我们的软件将从摄像头获取这些报告并将其存储在中央网络服务器上。

虽然我们可以将摄像机的 IP 插入到我们的软件中,但我正在开发一个简单的 Java 类来查询网络并定位网络上的所有摄像机。

但问题是,虽然它在我的 PC 和我同事的 PC 上运行得很好,但当我们尝试在将托管我们软件的实际网络服务器 PC 上运行它时......它运行,但说每个 IP 在子网离线/无法访问,除了网关 IP。

例如,如果我在连接到封闭的 LAN 时从我的 PC 或同事的 PC 上运行它,我会找到以下 Activity IP 以及一个标志,告诉我它是否是摄像头。(网关为192.168.0.1,子网掩码为255.255.255.0,表示要查找全范围256个设备)

IP:/192.168.0.1  Active:true Camera:false
IP:/192.168.0.100 Active:true Camera:true <- this is camera 1
IP:/192.168.0.101 Active:true Camera:true <- this is camera 2
IP:/192.168.0.103 Active:true Camera:false <- my PC
IP:/192.168.0.104 Active:true Camera:false <- this is our webserver

但出于某种原因,当从网络服务器 PC 运行相同的程序时,使用相同的 JRE,我只找到以下内容

IP:/192.168.0.1  Active:true Camera:false

现在我的代码不是在主线程上按顺序枚举每个 IP,而是为每个要检查的 IP 创建一个单独的线程并同时运行它们(否则枚举整个 IP 只需要 21 多分钟范围在 5000 毫秒/IP 超时)。然后,主线程每 15 秒一遍又一遍地重新运行这些 IP 扫描线程。

我已检查所有线程在所有 PC 上都运行完毕,没有抛出异常。甚至验证了没有线程被卡住。每个线程从开始到完成大约需要 5001 到 5050 毫秒,而那些具有 Activity IP 的线程会更快完成(>5000 毫秒),所以我知道它在 ipAddr.isReachable(5000) 方法中正确地等待了完整的 5000 毫秒。

我和我的同事在这一点上被难住了,当它在我们的 PC 上运行时似乎可以很好地访问那些活跃的 IP,但网络服务器 PC 没有响应???

我们已经排除了防火墙问题、管理员访问问题等。唯一的区别是我们的网络服务器是嵌入式 Win XP,而我们的 PC 是 Windows 7。

这让我们难住了。有什么想法吗?

下面是运行每个 IP 线程的代码:

public void CheckIP() {
new Thread() {
@Override
public void run() {
try {
isActive = ipAddr.isReachable(5000);
if (isActive) {
if (!isCamera) {
isCamera = new IpHttpManager().GetResponse(ipAddr.toString());
}
} else {
isCamera = false;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();

编辑:这是在根据网关和子网确定范围后构建要检查的每个 IP 的代码...

for(int i=subMin; i<=subMax; i++) {
byte[] ip = new byte[] {(byte)oct[0],(byte)oct[1],(byte)oct[2],(byte)i};
try {
scanners[subCount] = new IpScan(InetAddress.getByAddress(ip));
subCount++;
} catch (UnknownHostException e) {
e.printStackTrace();
}}

最佳答案

谢谢大家,但我从来没有弄清楚或查明为什么会发生这种奇怪的情况。我检查的一切都不是原因,所以这个问题可以关闭。

无论如何,我最终完全解决了这个问题。我没有使用 InetAddress,而是直接构建了自己的 ICMP ping 类,通过 JNA 调用 Windows 库 IPHLPAPI.DLL 和 WSOCK32.DLL。这是我用过的...

public interface InetAddr extends StdCallLibrary {
InetAddr INSTANCE = (InetAddr)
Native.loadLibrary("wsock32.dll", InetAddr.class);

ULONG inet_addr(String cp); //in_addr creator. Creates the in_addr C struct used below
}

public interface IcmpEcho extends StdCallLibrary {
IcmpEcho INSTANCE = (IcmpEcho)
Native.loadLibrary("iphlpapi.dll", IcmpEcho.class);

int IcmpSendEcho(
HANDLE IcmpHandle, //Handle to the ICMP
ULONG DestinationAddress, //Destination address, in the form of an in_addr C Struct defaulted to ULONG
Pointer RequestData, //Pointer to the buffer where my Message to be sent is
short RequestSize, //size of the above buffer. sizeof(Message)
byte[] RequestOptions, //OPTIONAL!! Can set this to NULL
Pointer ReplyBuffer, //Pointer to the buffer where the replied echo is written to
int ReplySize, //size of the above buffer. Normally its set to the sizeof(ICMP_ECHO_REPLY), but arbitrarily set it to 256 bytes
int Timeout); //time, as int, for timeout

HANDLE IcmpCreateFile(); //win32 ICMP Handle creator

boolean IcmpCloseHandle(HANDLE IcmpHandle); //win32 ICMP Handle destroyer
}

然后使用它们创建以下方法...

public void SendReply(String ipAddress) {
final IcmpEcho icmpecho = IcmpEcho.INSTANCE;
final InetAddr inetAddr = InetAddr.INSTANCE;
HANDLE icmpHandle = icmpecho.IcmpCreateFile();
byte[] message = new String("thisIsMyMessage!".toCharArray()).getBytes();
Memory messageData = new Memory(32); //In C/C++ this would be: void *messageData = (void*) malloc(message.length);
messageData.write(0, message, 0, message.length); //but ignored the length and set it to 32 bytes instead for now
Pointer requestData = messageData;
Pointer replyBuffer = new Memory(256);
replyBuffer.clear(256);

// HERE IS THE NATIVE CALL!!
reply = icmpecho.IcmpSendEcho(icmpHandle,
inetAddr.inet_addr(ipAddress),
requestData,
(short) 32,
null,
replyBuffer,
256,
timeout);
// NATIVE CALL DONE, CHECK REPLY!!

icmpecho.IcmpCloseHandle(icmpHandle);
}

public boolean IsReachable () {
return (reply > 0);
}

关于java - 奇怪的 InetAddress.isReachable() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19039646/

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