I am working on design of a device that are installed on clients networks. Currently there is about 180 devices installed arround the world. One major concern is to access them for debugging purpose later.
Context :
All devices work the same.
OS is Linux
Default mode is DHCP but sometimes Static IP
Currently the method to get addresses is :
Log on a computer of the client with any remote desktop software available and search with :
DHCP address in router's leases table (most of the time clients doesn't know their credentials)
Angry IP scanner, scan for port 22 (slow)
ping the name of the device (doesn't always work)
Expecting :
Actually I know it is possible to communicate with devices on network without knowing its IP address by broadcasting on the network but not found any example yet or start point. I would like to write a small Java program that will be able to broadcast on a network to :
List every devices with their IP
Assign IP address to device and/or other functions
Remember : I would like to find devices that have no keyboard, screen or other UI. If I receive a unit from a client (for debug purposes) that was configurated for example with 10.1.1.100 and my computer is on 192.168.1.110 (on the same switch), I want to be able first to know the IP address of this device, second, be able to send a SET IP command (I'll manage how to handle it once I'm able to send data).
For the server part of the device, I don't mind, it could be done in C++ or script... This will probably needed to answer to broadcast and receive requests.
So far, I've been able to create a small UDP client and server.
Client in Java using DatagramSocket, server in C using recvfrom().
The problem with this solution is that my computer need to have the same network mask as the device, example :
Device has 192.168.2.217
Computer has 192.168.1.110
My computer will need 255.255.0.0 as netmask, ortherwise I will not be able to broadcast 192.168.255.255.
Seaching more, the need to change the local computer netmask to meed broadcasting range seems to be a limitation of Java...
new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), PORT); // not working
new DatagramPacket(sendData, sendData.length, InetAddress.getByName("192.168.255.255"), PORT); // working only if netmask is 255.255.0.0
I think I will need to go deeper in network protocols to do it the way I want and that I know it is possible.
Related
So I'd like an automated network discovery for the application I'm currently building, but turns out we're not in a perfect world and neither does every network have IPv6 enabled for multicasting, nor is IPv4 UDP broadcast enabled in every network.
Any idea how I can programmatically find out, if either of those are enabled in the current network? Since UDP doesn't open a connection, I can just throw datagrams and hope someone finds it, then if noone else answers after a set time (or like, offer the user a button for manual discovery from the beginning) use user provided information (or a name service / registry I'd have to host somewhere).
Looks like sending a multicast is received on my own machine when I send it from one port to the other, but I can't be sure it actually goes out of the device and back in or it just loops back because it's being clever.
I'd prefer multicast of course - broadcast would be the fallback here.
Update
Tried things in the eduroam network:
Made new MulticastSocket and joined the multicast using joinGroup.
Made new DatagramSocker and sent a message to that multicast group
-> Works locally
-> Doesn't work across machines
Same with broadcast (interfaceAddress.getBroadcast()). Works locally (Sending from one port to another), but not across machines.
So how do I programmatically decide if these work?
I have an ESP8266 that connects to my WiFi network after being configured (via WiFi Manager library) and runs a HTTP web server that displays certain sensor data. It connects to my specific network with a 192.168.0.XX IP and it works well.
My problem comes with the android app, and how to actually programmatically retrieve the IP that the webserver is running on? My routers DHCP only reserves IP's for a week - so hardcoding the IP into the app is not a good option, and having less tech-savvy people find the IP and configure it themselves is also not what I'm looking to do.
I also can't hardcode a static IP as friends & family will be using this with different networks and routers (so 192.168.0.X would not work on a router with an IP of 10.0.0.1 for example).
So, how do I go about programmatically getting the IP of my ESP8266 that is connected to my local network?
There is a solution that maybe isn't very optimal and professional, but will do for hobby project. You can make your android app scan your local network using http GET on all addresses - e.g. trying to GET something like this: http://192.168.0.X/sensor_status. You can configure your esp8266 device to respond with code 200 (OK) and save this address in your android app's persistent storage. Next time you can simply check if there is ip saved in persistent storage and try to connect to it. If esp8266 is not available under remembered ip, you can re-scan your network.
as you can read in title I'm making a super simple IOT (Not really)
and
using a esp8266 and want to make it connect to my home wifi network and make a communication between a android app and the module (android app connects to home wifi)
Note : Iam Using CODE VISION AVR
you may say :
Why not directly connect to ESP when its on Server Mode?
that's fine cause when ESP is server "he" can set ip for him self so
ip will be always same BUT I want it to connect to home wifi
-
Why you wont connect with IP ?
you cant find the module ip easily because its given by Wifi
-
Find ESP ip using IP scanner
Its not possible cause it changes every time and user have to change
IP every time in android app AND my app cant scann every time it want
to connect to a single device its so dumb...
-
Do a Static Ip for ESP !
well that's not possible too because maybe that IP was taken by
someone before ESP send static IP AT command ! + if IP wasent taken it may taken after Home Wifi Restarts !
Sorry for bad English :X
You can use software serial to configure esp8266 from arduino. You need to know the setup circuit perfectly. Keep it in mind that esp8266 operates on 3.3V where arduino gives 5V output. The most important thing is to send AT commands to esp8266. You can use the following command to connect with your wifi.
AT+CWJAP="Your_WiFi","password"
If you need to see the ip address of esp8266, you can use this command.
AT+CIFSR
If you want to set static ip to esp8266 , then you can try this one.
AT+CIPSTA="ip module","ip gateway","subnet mask"
Use mDNS responder:
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266mDNS/examples/mDNS_Web_Server/mDNS_Web_Server.ino
This way you would be able to connect to ESP8266 via hardcoded url like http://esp8266.local.
I'm programming a client-server app, my client being an android phone, my server being my laptop.
So my issue is that this one line of code:
Socket connectionToServerSocket = new Socket(hostName, portNumber);
works perfectly fine when my cellular phone connects to the Internet with my home wifi connection, and simply times out when connected through 3G (cellular provider) eg it blocks for a while then throws a timeout exception.
The funky thing is,that I can see (using OS Monitor) that some apps are connected through very common ports, for example port #80, but switching portNumber (as well as the port that the server is listening to) to 80 doesn't help (eg it still times out), and I've tried many different ports-same result.
DNS works fine (eg it translates the logical String which I gave hostName to the correct IP) but it doesn't send the server anything...
I'm lost,what could be the reason? How can I check and resolve it?
I've run into this issue as well doing a similar application.
Your laptop and phone can connect to each other while on the same network because they share a IP address lookup through your router.
When the device is connected to the WIFI, it's request get passed through the router to check for IP addresses, it will find your laptops IP and save a request to a DNS because it can find the laptops IP already. The laptop works the same way, it finds the Ip address of the client through the router as well.
However, when your phone is on 3G, it has no way of knowing exactly where your laptop's IP address is. That's why it times out: it goes from your router to your nearest DNS (where it tries to resolve the correct IP Address), if it cannot find a domain or IP that matches it will fail.
Some steps to fix this . . .
Depending on your router you can set up port forwarding for your laptop's IP. This means incoming requests to your router can be piped to your laptop's server implementation.
Then go to any site like this http://touch.whatsmyip.org/ on your laptop to get your laptops IP. Save this to add to your clients Socket set up.
For debugging until your laptop server is visible for DNS lookup, go into your client code and add this.
Socket debugSocket = new Socket("the.laptop.ip", 80);
Some warnings:
Depending on your Router, your ip may change during restarts
With port-forwarding any browser with your ip, ex) 178.12.434.01 can log onto your laptops personal server
Future Changes:
Once a dedicated server is up and running, registered with a domain you can change the above ip parameter to "your.domain.com", and behind the scenes the actual IP address to your server will be found via DNS lookup.
the reason for that is that the server in your laptop is closed to external network by default, what you need to do is something called port forwarding
*take note: port forwarding put your server in a cyber security risk, make sure you make the right adjustments to keep your server safe.
case 1: It is working when your laptop and your phone is connected to wifi right ?
Try this once
case 2 :
connect your phone to 3G.
enable hotspot on phone.
connect your laptop to your phone's hotspot.
check the IP of your laptop if it is changed replace that in Socket object. Socket connectionToServerSocket = new Socket(newIP, portNumber);
Run your project.
Just try this once you will get what i am trying to say.
You are getting the timeout exception because your server that is
having the service is not reachable from the external network.
Hope this will help :)
I have two android devices - one is a server, second is a client. I run WiFi hotspot on server (using some external app, like QuickSettings), and then connect to this hotspot on second device. I have an application which transfers some data between these devices, so I need to get an IP address of the server to be able to create a socket on client. So my question is how can I do that inside my application (not justing by typing the proper IP manually)?
Did you try assuming the hotspot is the first IP in the valid range?
I mean: The hotspot gives you device an IP and a mask (and it should give even a gateway). The IP of the hotspot is the IP gateway, but if the hostspot did not tell your device such IP, the gateway is usually the first IP in the range allowed by the mask.