B4J Question Wrong IP Address returned by ServerSocket GetMyIP

max123

Well-Known Member
Licensed User
Longtime User
Hi all,
B4X:
Private Sock As ServerSocket
Log("IP: " & Sock.GetMyIP)

If Sock.GetMyIP = "127.0.0.1" Then
    LogError("This library need network connection. Please connect and try again")
    Return
End If
This code worked well for ten years in all my PC and on all B4J and B4A projects.

Today while network is disconnected, B4J fails and returned the IP address of VirtualBox virtual network interface instead of the loopback interface (127.0.0.1).
At this point Copilot said me to disable on ControlPanel the VirtualBox network.
After I desabled it, B4J returned the Hyper-V IP address. Copilot at this point said that it depends on the networks priorities, to change the loopback priority to 1 and other virtuals to 5000 with Shell.
This do not changed before and after reboot. without network B4J always return the Hyper-V IP address.
I tried to completely disable Hyper-V and reboot, now B4J return an IPv6 address.
I tried to completely reset my network settings and reboot again, but nothing changed, It always return other IP address than loopback.

I always used all this things without any problem, all always worked, but now it fail.

The only way I found to get my real IP address or "127.0.0.1" is to use Inline Java or JavaObject to iterate all network interfaces, put here some filters to filter some IP addresses that way:
B4X:
' Return IPv4 IP Adress (Wi‑Fi/Ethernet) if present.
' If not found return "127.0.0.1" that point to loopback.
Public Sub GetRealIPv4 As String
    Dim NI As JavaObject
    NI.InitializeStatic("java.net.NetworkInterface")
    Dim enNI As JavaObject = NI.RunMethod("getNetworkInterfaces", Null)
    If enNI.IsInitialized = False Then Return "127.0.0.1"
 
    Dim foundIP As String = ""
 
    Do While enNI.RunMethod("hasMoreElements", Null)
        Dim NI As JavaObject = enNI.RunMethod("nextElement", Null)
        If NI.RunMethod("isUp", Null) = False Then Continue
        If NI.RunMethod("isLoopback", Null) = True Then Continue
 
        Dim enAddr As JavaObject = NI.RunMethod("getInetAddresses", Null)
        Do While enAddr.RunMethod("hasMoreElements", Null)
            Dim ia As JavaObject = enAddr.RunMethod("nextElement", Null)
            Dim ip As String = ia.RunMethod("getHostAddress", Null)
            Log(ip)
            If ip.Contains(":") Then Continue ' IPv6
            If ip.StartsWith("127.") Then Continue ' loopback
            If ip.StartsWith("169.254.") Then Continue ' APIPA (VirtualBox)
            ' Exclude private range 172.16.x.x - 172.31.x.x (Hyper-V)
            If ip.StartsWith("172.") Then
                Dim parts() As String = Regex.Split("\.", ip)
                Dim secondOctet As Int = parts(1)
                If secondOctet >= 16 And secondOctet <= 31 Then Continue
            End If
            foundIP = ip
            Exit ' trovato un IPv4 valido
        Loop
 
        If foundIP <> "" Then Exit
    Loop
 
    If foundIP <> "" Then
        Return foundIP
    Else
        Return "127.0.0.1"
    End If
End Sub

I want to know if this is a problem on my PC or if other users have similar results, or may
depends of latest B4J releases, or may depends from automatic Windows updates.
The fact is that now it fails and I never installed any other programs to change this, I just updated to B4J 10.30 and
some days ago I had to reboot my PC because operating system updates required it.

Now I still develop a library that require network and I cannot proceed.

Many thanks
 
Last edited:

MicroDrie

Well-Known Member
Licensed User
Longtime User
@max123 Listen, what's done is done. We can only help you if you clearly explain what you want to achieve. You don't realize you're creating a complete smokescreen around your problem. What went wrong is impossible to figure out anyway. We have to go back to the drawing board and rebuild everything based on what you want to achieve. That's only possible if you follow the steps in my previous post. The beauty and the horror of it all is that you can implement many network solutions. Some of them work, some don't.
But you have to know where everything is and who needs to talk to whom from which location. You can place virtual hosts in a VLAN that can or cannot communicate with each other host in and outside that VLAN. The same goes for allowing or blocking traffic between VLANS and from VLANS to the internet.
Either you draw the requested network, then we can look into it, or you keep throwing smoke bombs, and then I'll start doing what you in Italy would call "Il Dolce Far Niente," or enjoying the sweet/blissful nothingness. The choice is yours.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
@max123 As I read again your post... may be the problem is just the choice between NAT or BRIDGE at settings of virtual machine... (BRIDGE will use your real network card)

another tweak / tip is the hosts file at windows\system32\drivers\etc

What you really want to take as answer from any ip or domain (fake)... will return it - as you want. May be this fix anything for you...


ps: Have in mind, hosts file has no extension - So first you must copy it at a folder your have permissions for editing - edit it - and save it without .txt or any other extension - then copy it back to the folder of windows
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Seem like loopback have lower priority as InterfaceMetrics, than other interfaces, so may it prevent Socket.GetMyIP to get a software loopback targeted as i in ifIndex. InterfaceMetrics should not be set to 1 to have highter priority ?
1757167690546.png
 
Last edited:
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
I see this is a very long thread and it seems to me that the issue hasn't been resolved.

Try asking some AIs to read the thread, providing them with the URL, and resolve it (not all AIs can "navigate"; start with ChatGPT).
Yes @LucaMs the issue was not solved.
I asked to ChatGPT, I asked to Copilot, tried to change metrics but without success, and nothing changed from my first post.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Yes @LucaMs the issue was not solved.
I asked to ChatGPT, I asked to Copilot, tried to change metrics but without success, and nothing changed from my first post.

Perplexity:

Here's a more complete B4J code for obtaining a reliable IP address, which takes into account issues with multiple virtual interfaces and the possibility of a disconnected network. The idea is:

Use JavaObject to iterate through all network interfaces

Filter virtual IPs, loopback, link-local (APIPA), and IPv6

If no valid IP is found, force a return of 127.0.0.1

Add a network connectivity check using a ping attempt to decide whether to use network IPs or force a fallback to loopback.

B4X:
Sub GetReliableIPv4 As String
    Dim NI As JavaObject
    Dim Runtime As JavaObject
    Runtime.InitializeStatic("java.lang.Runtime")
    Dim enNI As JavaObject
    NI.InitializeStatic("java.net.NetworkInterface")
    enNI = NI.RunMethod("getNetworkInterfaces", Null)
    If enNI.IsInitialized = False Then Return "127.0.0.1"
    
    Dim foundIP As String = ""
    
    ' Funzione interna per ping test (ret true se ping a 8.8.8.8 va a buon fine)
    Sub CheckInternetConnectivity As Boolean
        Try
            Dim Process As JavaObject = Runtime.RunMethod("exec", Array("ping -n 1 8.8.8.8"))
            Dim InputStream As Object = Process.RunMethod("getInputStream", Null)
            Dim Scanner As JavaObject
            Scanner.InitializeNewInstance("java.util.Scanner", Array(InputStream))
            Dim output As String = ""
            Do While Scanner.RunMethod("hasNextLine", Null)
                output = output & Scanner.RunMethod("nextLine", Null) & CRLF
            Loop
            Return output.ToLowerCase.Contains("reply from")
        Catch
            Return False
        End Try
    End Sub
    
    Dim hasConnectivity As Boolean = CheckInternetConnectivity
    
    Do While enNI.RunMethod("hasMoreElements", Null)
        Dim netInterface As JavaObject = enNI.RunMethod("nextElement", Null)
        
        ' saltare interfacce non attive o di loopback
        If netInterface.RunMethod("isUp", Null) = False Then Continue
        If netInterface.RunMethod("isLoopback", Null) = True Then Continue
        
        Dim enAddr As JavaObject = netInterface.RunMethod("getInetAddresses", Null)
        Do While enAddr.RunMethod("hasMoreElements", Null)
            Dim ia As JavaObject = enAddr.RunMethod("nextElement", Null)
            Dim ip As String = ia.RunMethod("getHostAddress", Null)
            
            If ip.Contains(":") Then Continue ' IPv6
            
            ' ignorare loopback o localhost
            If ip.StartsWith("127.") Then Continue
            
            ' ignorare APIPA address VirtualBox
            If ip.StartsWith("169.254.") Then Continue
            
            ' ignorare subnet Hyper-V 172.16.0.0 - 172.31.255.255
            If ip.StartsWith("172.") Then
                Dim parts() As String = Regex.Split("\.", ip)
                Dim secondOctet As Int = parts(1)
                If secondOctet >= 16 And secondOctet <= 31 Then Continue
            End If
            
            ' se c'è connettività internet, accettare il primo IP valido
            If hasConnectivity Then
                Return ip
            Else
                ' se non c'è connettività internet, salvare l'IP se non è virtuale noto
                foundIP = ip
            End If
            
        Loop
        
    Loop
    
    ' Se no connettività e non abbiamo trovato IP valido diverso, fallback a 127.0.0.1
    If foundIP <> "" Then Return foundIP
    Return "127.0.0.1"
End Sub

Explanations

CheckInternetConnectivity pings 8.8.8.8 to determine if the machine has external access.

If the network is reachable, it returns the first valid IP that is not virtual, loopback, APIPA, or IPv6.

If the network is unreachable, it searches for a valid non-virtual IP, but otherwise returns 127.0.0.1.

This approach balances the issue of multiple virtual interfaces and the lack of a physical network.

This method can be integrated into your project to replace ServerSocket.GetMyIP and obtain a more reliable result under all network conditions.
 
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
Perplexity:

Here's a more complete B4J code for obtaining a reliable IP address, which takes into account issues with multiple virtual interfaces and the possibility of a disconnected network. The idea is:

Use JavaObject to iterate through all network interfaces

Filter virtual IPs, loopback, link-local (APIPA), and IPv6

If no valid IP is found, force a return of 127.0.0.1

Add a network connectivity check using a ping attempt to decide whether to use network IPs or force a fallback to loopback.

B4X:
Sub GetReliableIPv4 As String
    Dim NI As JavaObject
    Dim Runtime As JavaObject
    Runtime.InitializeStatic("java.lang.Runtime")
    Dim enNI As JavaObject
    NI.InitializeStatic("java.net.NetworkInterface")
    enNI = NI.RunMethod("getNetworkInterfaces", Null)
    If enNI.IsInitialized = False Then Return "127.0.0.1"
  
    Dim foundIP As String = ""
  
    ' Funzione interna per ping test (ret true se ping a 8.8.8.8 va a buon fine)
    Sub CheckInternetConnectivity As Boolean
        Try
            Dim Process As JavaObject = Runtime.RunMethod("exec", Array("ping -n 1 8.8.8.8"))
            Dim InputStream As Object = Process.RunMethod("getInputStream", Null)
            Dim Scanner As JavaObject
            Scanner.InitializeNewInstance("java.util.Scanner", Array(InputStream))
            Dim output As String = ""
            Do While Scanner.RunMethod("hasNextLine", Null)
                output = output & Scanner.RunMethod("nextLine", Null) & CRLF
            Loop
            Return output.ToLowerCase.Contains("reply from")
        Catch
            Return False
        End Try
    End Sub
  
    Dim hasConnectivity As Boolean = CheckInternetConnectivity
  
    Do While enNI.RunMethod("hasMoreElements", Null)
        Dim netInterface As JavaObject = enNI.RunMethod("nextElement", Null)
      
        ' saltare interfacce non attive o di loopback
        If netInterface.RunMethod("isUp", Null) = False Then Continue
        If netInterface.RunMethod("isLoopback", Null) = True Then Continue
      
        Dim enAddr As JavaObject = netInterface.RunMethod("getInetAddresses", Null)
        Do While enAddr.RunMethod("hasMoreElements", Null)
            Dim ia As JavaObject = enAddr.RunMethod("nextElement", Null)
            Dim ip As String = ia.RunMethod("getHostAddress", Null)
          
            If ip.Contains(":") Then Continue ' IPv6
          
            ' ignorare loopback o localhost
            If ip.StartsWith("127.") Then Continue
          
            ' ignorare APIPA address VirtualBox
            If ip.StartsWith("169.254.") Then Continue
          
            ' ignorare subnet Hyper-V 172.16.0.0 - 172.31.255.255
            If ip.StartsWith("172.") Then
                Dim parts() As String = Regex.Split("\.", ip)
                Dim secondOctet As Int = parts(1)
                If secondOctet >= 16 And secondOctet <= 31 Then Continue
            End If
          
            ' se c'è connettività internet, accettare il primo IP valido
            If hasConnectivity Then
                Return ip
            Else
                ' se non c'è connettività internet, salvare l'IP se non è virtuale noto
                foundIP = ip
            End If
          
        Loop
      
    Loop
  
    ' Se no connettività e non abbiamo trovato IP valido diverso, fallback a 127.0.0.1
    If foundIP <> "" Then Return foundIP
    Return "127.0.0.1"
End Sub

Explanations

CheckInternetConnectivity pings 8.8.8.8 to determine if the machine has external access.

If the network is reachable, it returns the first valid IP that is not virtual, loopback, APIPA, or IPv6.

If the network is unreachable, it searches for a valid non-virtual IP, but otherwise returns 127.0.0.1.

This approach balances the issue of multiple virtual interfaces and the lack of a physical network.

This method can be integrated into your project to replace ServerSocket.GetMyIP and obtain a more reliable result under all network conditions.
Carissimo Luca, grazie per l'interesse, ecco il link alla discussione con ChatGPT.
Dear Luca, many thanks for your interest, here a link to ChatGPT session.
https://chatgpt.com/share/68bc4aba-5064-8007-aee4-f796c6a0181a
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Upvote 0

max123

Well-Known Member
Licensed User
Longtime User
?
Mi indichi che ChatGPT non ha risolto? Me lo hai già "detto"
Prova con quel codice di Perplexity (ovviamente con pochissima speranza, come sempre 😄)


Are you telling me ChatGPT didn't solve the problem? You already "told" me.
Try that code from Perplexity (obviously with very little hope, as always 😄)
I posted the link, I don't know what you mean ... "Are you telling me ChatGPT didn't solve the problem?"
I don't have to do it by software, I have to Reset my network system settings, manually, something changed here, loopback have lower priority now, than other interfaces.

Thanks for your code, this by @Daestrum do not return IP address but it even works well:
B4X:
Private Sub DeviceIsOnline As Boolean
    Try
        Return (Null).As(JavaObject).InitializeStatic("java.net.InetAddress").RunMethodJO("getByName", Array("8.8.8.8")).RunMethod("isReachable", Array(1000)) ' timeout in ms
    Catch
        Return False
    End Try
End Sub

Referred to the screnshot on post #43
1757174493263.png
 
Last edited:
Upvote 0
Top