How to check local network IP address

Can anyone tell me how to check if a local network IP is live or not.

I have tried this :

 result = net->gethostbyname("192.168.1.200", &a);
    if (result != 0) {
        printf("Error! Could not resolve host 192.168.1.200. Result: %d\n", result);
    }

But I always get ‘0’ result if the IP is live or not.

The example here does work with a ‘name’ but not when I try with a local IP

 result = net->gethostbyname("ifconfig.io", &a);
    if (result != 0) {
        printf("Error! Could not resolve host ifconfig.io. Result: %d\n", result);
    }

So It tried this as a ‘get round’:
If I connect with setting a 2 second timeout to a non valid IP I get -3004 error after 30 seconds which is un-usable.

    client.set_timeout(2000);   
    result = client.connect(net_addr); 
    printf ("connect result: %d\n",result); 

with a valid IP it connects in less than 3 mS

I would like to set a short timeout of 50 mS, check if the IP is ‘live’ then communicate if its available.

Any help would be appreciated.

1 Like

After digging around a bit more I’ve trimmed the code to this:

    TCPSocket remote_device;
    SocketAddress remote_addr("192.168.1.150",80);
    remote_device.open(net);        

    remote_device.set_timeout(2000);  
    
    t1.reset();t1.start();  
    remote_device.connect(remote_addr); 
    t1.stop();
    printf ("connect time: %f\n", t1.read()); 
           
    char sbuffer[] = "GET /data\r";    
    remote_device.sendto(remote_addr, sbuffer, sizeof(sbuffer));       
    
    char *rbuffer = new char[64];    
    remote_device.recvfrom(&remote_addr, rbuffer, sizeof(rbuffer));

Apparently set_timeout is not implemented on socket connect(). So if you have a dead IP the system waits for 30 seconds before resuming. I can’t see any other way to check for a ‘live’ IP other than connect() with a time out.
I have sent an ‘issue’ on Github for set_timeout to be added to the connect() function.

if I do not use:

 remote_device.connect(remote_addr);

the sendto and recvfrom functions do not work, I thought that was only needed with send and recv functions?

Hello Paul,

I think the program is paused for about 30 seconds in the lwip_netconn_do_connect function while it is waiting for a semaphore with 0 timeout (until the semaphore is cleared) when calling :

...
sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
...

You can modify this behaviour for example by setting a 50ms timeout:

...
sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 50);
...

The lwip_netconn_do_connect function is implemented in the mbed-os/features/lwipstack/lwip/src/api/lwip_api_msg.c file.

Best regards,

Zoltan

Hello Zoltan, thank you for coming back on this one.

I did make that change (line 1394 of OS5.15 in offline Studio) and yes it did work to a degree.
The delay changed to 50ms on both a non-valid or valid IP.
Valid IP connect time is normally 2-3ms.
So it appears to be ‘latching’ that connect function for 50ms period.

Then after several connections at 1 second intervals I got the ‘text of death’ below…

++ MbedOS Error Info ++
Error Status: 0x80010134 Code: 308 Module: 1
Error Message: Semaphore: 0x834FF0E9, Parameter error
Location: 0x804A2F9
Error Value: 0x834FF0E9
Current Thread: lwip_tcpip Id: 0x2000BF64 Entry: 0x8049EC9 StackSize: 0x4B0 StackMem: 0x2000D870 SP: 0x2007FF58
For more info, visit: mbedos-error
– MbedOS Error Info –

There are a lot of #defines in the sys.h file with this comment:

/* For a totally minimal and standalone system, we provide null
definitions of the sys_ functions. */

Probably quite a few changes required here, however I did open an issue on Github:
https://github.com/ARMmbed/mbed-os/issues/13056

Kind regards

Paul

Hi Paul, I am sure there must be an async connect API, however I have not done TCP/IP with Mbed so far. For this I use the ESP32 with WiFi or the W5500 Ethernet Module which has a own TCP/IP stack build in.

BTW: a gethostbyname resolves only the string into an IP address, some DNS requests may be involved, however it does not connect to the host. You need to do a successful connect to verify that the server up and accepting connections.

Regards Helmut

Hi Helmut, thanks for clearing up my confusion with gethostbyname function.

I too use the ESP8266 (but not with the Mbed driver) and have been able to use CIPSTART to test for a ‘live’ IP without too much trouble although there is some delay with TCP/IP stack response for me to get the CIPSTATUS to ‘4: The TCP or UDP transmission of ESP8266 Station is disconnected’

The problem is I need TLS for a HTTPS connection over the internet, so I need to use the Mbed drivers.
The 30 second delay for a dead IP response is unusable unless there is a way to reduce it.
A one second delay would be usable.

Regards Paul

Here’s the (or a working) solution.

Chang the nonblocking sequence in the LWIPStack.cpp file (around line 350) as below…

// original
netconn_set_nonblocking(s->conn, false);
err_t err = netconn_connect(s->conn, &ip_addr, address.get_port());
netconn_set_nonblocking(s->conn, true);

// replace with
netconn_set_nonblocking(s->conn, true);
err_t err = netconn_connect(s->conn, &ip_addr, address.get_port());

This now enables the timeout for the connect function, I use 100ms to 200ms but works at 10ms for fast small data packets.