I don’t think that it is possible to bind a socket to a non-local IP. At least not without modifying the TCP stack code. Since using a different address means that IP stack needs to allow packets with different IP address than the local one which is not a simple change.
Can you tell me why do you need a different IP address? Maybe we can find a way around this problem.
What happens is that I need to identify my hardware on a local network. I’m currently pinging all the IP addresses from the app. That is, if the network segment is 192.168.0.xx, I make a pin from 192.168.0.1 to 192.168.0.254.
Those addresses that respond, I try to open a socket and send a data frame, if the answer is correct, I assume that I have found a hardware in my local network (there could be more than one connected)
Obviously those IP addresses that don’t respond, or that the socket cannot be opened or that they respond to something wrong are discarded.
Those valid addresses are displayed in a list for the user to choose with which to interact.
Also, these valid addresses are saved in the application so that the next time the app is opened, it will automatically connect to the stored addresses, avoiding the scanning of the IP addresses.
This seems correct to me the first time the user installs the hardware and configures with the app
The problem is that I was informed that there are users that their routers are configured to renew their IP addresses once a month.
If this happens, the app should again perform a scan of all the IP addresses again, and this is somewhat cumbersome, since scanning all the IPs takes some time, I don’t think users are happy configuring their app and hardware once a month.
Another cumbersome solution could be to use static IP addresses, but I don’t think that’s a good idea either.
So doing some research, the suggestion I found on how to find hardware in a local network is using UDP broadcast or multicast.
This is a UDP server at Multicast IP addresses (range of 224.0.0.0-239.255.255.255).
What the application has to do is open a socket to connect to the UDP server and through that message it would obtain the dynamic IP and other possible parameters.
That way I avoid making a pin of all the IPs and everything explained above.
It is still not clear to me what you are trying to do, but note just because the IP address is being refreshed doesn’t mean it won’t be assigned the same address again. Most DHCP servers will try to give the same MAC address the same IP address each time - although that is not guaranteed.
Are you asking how to define the IP address of a remote socket you want to send data too? If so I think that is done in the sendto() function. Or are you asking how to use a broadcast packet to send data to a particular IP address? Or something else?
the problem you are trying to address is as old as networking itself. A TCP/UDP server whose IP address is subject to change (eg via dhcp) is a “moving target” for clients.
Normally this is addressed through protocols like DynDNS. Your envisioned solution will not work.
Hello @DominusDRR, the sin_addr that you set (or don’t) in the xAddress will not be used. The socket will be bound to a port with the device’s local IP.
I agree with @RAc, generally these problems involve some kind of Name service or a server which acts as a mediator between two devices.
You may want to try out LLMNR where the target device can be queried. You’ll need to enable ipconfigUSE_LLMNR. See here for more details.
It’s been a while since I’ve used UDP, but it does not create a connection. You send to a UDP port, but unless the app is designed to respond, you don’t get a response. It’s a fire-and-forget protocol. As a result, you can send to another app, or listen for messages from that app. If the app knows to send a response (to a location within the UDP data), you never know it’s received it.
In UNIX/Linux you don’t connect, just send to a network tuple, or receive on a network tuple.
That will only work if your MCU has multiple network interfaces, eg a cabled and a wireless interface. Per interface there is only one IP address, either static or dynamic.
As a real world example of what @wdtj outlined, consider SNMP. That’s a UDP based bidirectional protocol, meaning your unit acting as an SNMP agent can both receive and send SNMP packets from/to the same server. If your unit HAD two IP addresses to choose from, it wouldn’t know which address to use as the source address for outbound diagrams as inbound and outbound packets are completly independent. The SNMP server would get fairly confused if it did send out SNMP commands to the static address but received SNMP traps from the same agent from a dynamic address, or worse, varying addresses.
The TCP/IP suite isn’t designed for this kind of thing. Again, the moving target issue has been around forever, caused tens of thousands of developers to scratch their heads, and if there WAS an easy and straightforward solution, it would be well documented and easily accessible. Funnily enough, it isn’t even though it’s an ubiqutous issue. Again, the most widely used workarounds all use logical names such as DNS or LLMNR, as @kanherea suggested.
Well, taking the idea of LLMNR, and accepting that when opening a UDP socket in the microcontroller which will have as IP the one that the router has dynamically provided, what I have to do is send a data frame to address 224.0 .0.252 and it would look something like this:
While on the mobile phone application side, it should open the UDP socket with the address “224.0.0.252” waiting for some data from the microcontroller.
Obviously, as @wdtj mentioned, when the MCU sends the frame with data, there is no guarantee that the receiver (the app) will receive the message, so I think it should be periodically sending the data frame from the microcontroller to address “224.0.0.252”., until at some point the app manages to capture the data.
No, but I encourage you to give it a try and figure out for yourself why this won’t work. Instead of thinking up some pseudo code and then asking whether that’s valid code or not, the better strategy would be to make the code real code and then see what happens. You learn more that way and save turnaround time.
Then go ahead and try to process the data in your simulated MCU.
Bonus points: Imagine two of your units sitting in the same network. How does either of the two know which packet is directed to it when the mobile phone app serves both? After all, they both “use” the same IP address, right?
You should try to get a good grip of addressing, ie understand the ISO/OSI layering, the different types of addressing (MAC, IP, logical…), what those are for and which layer can see each of them.
Again, experiment and learn by doing. A lot of things will fall into place that way.
That is the magic of ‘Multi-cast’, and why a Node needs more than just the Multi-cast address.
Routers need to be able to keep track of multiple entries for IP → MAC translaslation for Multi-cast IP addresses. There is no problem with sending a single packet to a Multi-cast IP address and it getting to multiple nodes, that’s just how Multi-cast works.
Now, none of those nodes would normally reply with a source address of the Multi-cast IP, as that isn’t the nodes ‘real’ IP address.
I agree with that. Just play with the protocols and see what happens!
I have tried all possibilities that you mention. Mind you that LLMNR is using multicast.
My devices are amplifiers, and each one has a unique name, for instance: “ampli-1” up to “ampli-10”.
Now thanks to LLMNR I can ping a device as simple as this:
ping ampli-1
Or I can telnet it:
telnet ampli-2
Now I also gave them a common name, e.g. “amplifier”. When I “ping amplifier”, all devices will respond to the LLMNR lookup. The first response will be used by ping.