Odd InetAddress.isReachable() issue

前端 未结 2 476
春和景丽
春和景丽 2020-12-10 20:09

My work is developing software for network capable cameras for retail enviroments. One of the peices of software my team is developing is a webserver that retrieves various

2条回答
  •  一个人的身影
    2020-12-10 21:11

    Thanks everyone, but I never did figure out or pinpoint why this oddity was happening. Everything I checked for was not the cause, so this question can be closed.

    In any case, I ended up working around it completely. Instead of using InetAddress, I just went native and built my own ICMP ping class instead, via JNA, invoking Windows libraries IPHLPAPI.DLL and WSOCK32.DLL. Here is what I used...

    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
    }
    

    And then using those to create the following method...

    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);
    }
    

提交回复
热议问题