What’s a way in Xojo for a program to:
a. find the IP address of the computer the app is running on
b. find the “outside world” IP address (on the “other side” of the router)
a) you can get away with just creating a new TCP Socket and reading the local address
You dont need to connect or anything
b) usually requires a service on the other side of the router that can look back at a request and say “your IP is …”
services like https://www.whatsmyip.org/
is there a way to get your public ip address without any web service ?
as many of them are prone to dissapear sooner or later
using arp shell commands or something like that ?
possibly query your router for its external ip address
I would like to stay independant of the router.
I know my public ip address I don’t need any program to that !
I want to implement it in a xojo program, cross platform and rweb service and router independant … if possible.
I’ll probably just use ipify. Hopefully it’s not going anywhere soon.
short of asking the router or an external service I dont know of a way to get your public ip address
Here is the code I use:
#If TargetDesktop Or TargetWeb Then
Var pubip As String
Var sck As New HTTPSocket
Try
Var js As New JSONItem(sck.Get("http://ipinfo.io/json", 10))
If js.hasname("ip") Then pubip = js.value("ip")
Catch RuntimeException
pubip = ""
End Try
If sck <> Nil Then sck = Nil
Return pubip
#EndIf
ipinfo.io sounds like it’s the same sort of service as the one I mentioned, ipify.org.
I guess if one fails you can try the other! 
having a list of several you can try if one fails is probably prudent
I tried this, but while it displays the IP address on the iphone simulator, it doesn’t display it when on the iPhone connected to the computer. // Function GetLocalIPAddress() As String
#If TargetIOS Then
// iOS doesn’t support NetworkInterface, so use socket method
Try
// Create a new TCP socket
Var sock As New TCPSocket
// Set destination to Google's public DNS (we won't actually connect)
sock.Address = "8.8.8.8"
sock.Port = 80
// Attempt connection - this makes iOS select which network interface to use
sock.Connect
// Get the local IP that iOS selected for this connection
Var localIP As String = sock.LocalAddress
// Close the socket
sock.Close
// Return the IP if it's valid (not empty and not localhost)
If localIP.Trim <> "" And localIP <> "127.0.0.1" Then
Return localIP
End If
Catch err As IOException
// Connection may fail, but we still get the local address before failure
End Try
// No valid IP found
Return “”
#Else
// Desktop version: loop through all network interfaces
For i As Integer = 0 To System.NetworkInterfaceCount - 1
// Get the interface at this index
Var Interface As NetworkInterface = System.NetworkInterface(i)
// Skip localhost (127.0.0.1)
If Interface.IsLoopback Then Continue
// Get this interface's IP address
Var address As String = Interface.IPAddress
// Check if we have a valid address
If address.Trim <> "" Then
// Check if it's IPv4 (IPv6 addresses contain colons)
If address.IndexOf(":") = -1 Then
// Skip auto-assigned link-local addresses (169.254.x.x)
If Not address.BeginsWith("169.254.") Then
Return address
End If
End If
End If
Next
// No valid IP found
Return “”
#EndIfWhen I ran the code provided by DavidCox using this Var localIP As String = GetLocalIPAddress()
If localIP <> “” Then
MessageBox("Local IP Address: " + localIP)
Else
MessageBox(“No valid local IP address found.”)
End IfI got a message saying No valid local IP address found. The code I used works on the simulator, but doesn’t seem to give a message on the actual iPhone.
It may NOT have a IP
Plus I don’t think sockets start up the appropriate radioes (I know they didnt used to) to get an IP address
Put a little php script on your own web server to echo you the IP.
You may need entitlements or plist entries to use network stuff on iOS.
<?php
echo $_SERVER['REMOTE_ADDR'] ?? 'IP not available';
?>
In Java lang I would do it like this to get all informations of my local site:
import java.net.;
import java.util.;
public class Main {
public static void main(String[] args) {
try {
Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
while( networkInterfaceEnumeration.hasMoreElements()){
for ( InterfaceAddress interfaceAddress : networkInterfaceEnumeration.nextElement().getInterfaceAddresses())
if ( interfaceAddress.getAddress().isSiteLocalAddress())
System.out.println(interfaceAddress.getAddress().getHostAddress());
}
} catch (SocketException e) {
e.printStackTrace();
}
}
}
I really doubt that XoJo has any kind of functionality to do that. What you could do is getting this from the command line and filter the result out. I guess that’s the only chance to do that only with local tools without connecting any kind of Webserver which is able to readout your address.
That gives you at least the chance. With ifconfig you get a big amount of informations but one of the blocks should return for example for eth0:
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=50b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV,CHANNEL_IO>
ether 14:98:77:34:b0:44
inet6 fe80::18f9:3626:8cc7:5152%en0 prefixlen 64 secured scopeid 0x6
inet 10.0.0.14 netmask 0xffffff00 broadcast 10.0.0.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect (1000baseT <full-duplex,flow-control,energy-efficient-ethernet>)
So you could filter that String return and get - in this case 10.0.0.14 which is the local address. The external IP address which means in most cases the router’s address you can’t get with this kind of tools cause you can’t reach it from your position in. network. Only the local adress of your local PC network adapter is what you will get.
Why? You are not creating a socket…
Oh, that was while a socket was in that code before also sorry
I mean why bother catching SocketException, when you are not creating a socket?
There is similar functionality in 8th:
needs net/active
2 json-pretty
net:active? . cr
Outputs a JSON map:
{
"IPV4":[
{
"desc":"Intel(R) Ethernet Connection (16) I219-V",
"mac":"84:ba:59:5c:dc:6c",
"cast":"224.0.0.1",
"name":"{E068B2FC-1C03-4247-AAB2-AC3B889559AD}",
"fname":"Ethernet",
"addr":"10.84.205.47"
}
],
"IPV6":[
]
}
Finding out the external IP address can be done easily by sending and receiving UDP packet.
Below is a 8th code for finding out the external IPV4 address:
net:INET4 net:DGRAM net:socket var, socket
[ xaa, xaa, x01, x00, x00, x01, x00, x00, x00, x00, x00, x00,
"myip", "opendns", "com", x00, x00, x01, x00, x01 ] "12b1s1c1s1c1s1c5b" pack var, message
: address-info \ -- ai
"resolver1.opendns.com" 53 net:getaddrinfo ;
: app:main
address-info null? if
"Server address lookup failed.\n" . bye
then
socket @ swap message @ 0 net:sendto null? if
drop net:close
"Error sending message.\n" . bye
then drop
512 b:new 0 net:recvfrom null? if
drop "No response from the server.\n" .
net:close bye
then
\ Test RCODE
over 3 b:@ nip 0xf n:band !if
\ Last four bytes from the response is the IP address.
dup 4 n:- swap b:slice "4:1B" unpack drop
' >s a:map "." a:join
"External IP: %s\n" s:strfmt .
else
2drop "Error communicating with the server.\n" .
then
drop net:close ;