So i want to create an Android application that would send data (in this case coordinates) from my Android device to a Java application on my MacBook via Wi-Fi.
I figured i would use TCP Sockets for the job, and my Android device would act as client while my MacBook as server.
My problem is that in reality hardcoding IP addresses is not the ideal techique for that, is there any way around this? Is using Sockets the best way to make an application like that?
Not getting into the best way to do it, but instead of static ips use a Dynamic Dns Service.
You could use dynamic DNS. With dynamic DNS, client (Macbook) registers its IP address with DNS server, which than serves it to other clients (Android) via normal DNS requests.
However, I'd recommend against this setup (server on notebook with DynDNS):
Your notebook might not be always available, due to personal reasons or network connectivity reasons.
Network address translation (NAT): most client networks (wlan, home networks, even mobile networks) use this technology which prevents initiating TCP connections from internet to internal network (inbound connections). This can be alleviated via port forwarding, but this can only be done on networks that you control.
Instead I'd suggest that you use a virtual private server (Linode) or a cloud solution.
Alternatively, if you don't want to setup/manage a server, than you could use an existing data exchange solution: email, twitter, xmpp, etc..
Related
I have a use-case for Android devices that I can't seem to wrap my head around. The gist of it is I want to be able to send an API command from my server to my Android app over the Internet. The solution already works if my server application is hosted on the LAN: each Android device has an IP, and I send the command to each device's IP. What if my server is on the cloud? Is there a way for my server application to connect to my Android device directly without the need for a local server?
In this use-case, the Android devices are connected to network through either WiFi or ethernet, and the network has internet access.
Any suggestion would be wonderful, thank you!
When you are in local area network, both your server and client (Android device) are assigned with virtual IPs so there is no problem with see each other.
But when your move your server application to cloud, it cannot see your Android device anymore since your device is hidden by NAT. Only the gateway(your wifi router) IP can be seen by the server.
Some ways you can try:
Assign a static IP for your Android device, and configure your gateway to make a port forwarding to redirect the network traffic to your device. Then your server can see your device by sending to your-gateway-ip:port. But this is usually not a preferred way, unless you can always have full control of the client side network environment.
Change the application protocol to something like MQTT. In such case both your server and client can connect to this "broker" server so exchanging data is possible regardless of your client is under NAT or not. However, you may need to setup this extra broker server.
Find other third party notification services to do this server to client communication, such as Google Firebase.
I am writing a p2p messaging Android app, and I'm trying to solve the problem of NAT on mobile networks. I cannot currently find a way for a device to connect to another listening device on a 3G/4G network due to the carrier's NAT service.
I have heard of a few NAT punch-through methods, but a lot of those involve using some sort of centralized server as a mediator. I am trying to use a completely decentralized p2p approach to accomplish this task.
Are there any feasible ways of allowing a device on a mobile network to be publicly addressable?
Thanks!
No, it is not possible. Most of the time, subscribers with IP addresses NATed are behind NAT444 and many subscribers are anycasted ( subscribers have the same IP on their mobile phone, but nated behind a different NAT devices). And 2 anycasted suscribers cannot communicate together.
The only way left you is to open a VPN to get a real IP of Internet Public.
My suggestion would be: Do not use VPN for IPv4 ! Use VPN to get a real IPV6 to your mobile phone application, and build your p2p application over IPv6.
You are fighting with very old problem that drove IETF to build IPv6.
So, go to IPv6, and forget ipv4.
The ONLY good solution for your problem is to build your app over IPv6, and your app has to bring the ipv6 tunnel to the phone.
I want to connect 2 or more Android devices with p2p connection. As I understand I may use Wi-Fi Direct under one wifi network https://developer.android.com/guide/topics/connectivity/wifip2p.html
But I want to connect Android clients located in different places but possibly with the one IP (vpn or something). How can I do that?
Here is my algorithm
Client_1 register its name and current IP on Server
Client_2 register its name and current IP on Server
Client_1 request registred IP from Server by Client_2 name
Client_2 request registred IP from Server by Client_1 name
Client_1 send message directly to Client_2 IP
This algorithm will not work if Client_1 and Client_2 has the same IP. Or if client is behind NAT.
Is there a ready to use library to connect 2 or more Android devices in such way?
You can use Fixed Ip Simcards if you want to do a setup for your personal purpose. Another option is to convert your android phone local private ip into public ip , this can be done via Update No-IP app , this app will give you a direct link to communicate with public ip you have.
I hope my answer would be somewhat helpful to you.
Your best bet would be to look into NAT traversal on cellular connections. There are several threads on Stack Overflow that discuss this for example UPnP NAT Traversal for 3G/4G Wireless Data Connection on Android and Android: NAT Traversal?
To sum things up the easiest solution would be to look into using STUN to determine if your application/device is NATed and then using TURN or ICE to try to establish a (not necessarily direct) connection between your devices using NAT traversal. There exist multiple libraries that implement these protocols/methods for example http://www.pjsip.org/ which has Android support and has a pretty good documentation including sample applications for all mentioned techniques.
Im developing an app which uses the tcp connection. currently im communicating using hard coded IP addresses as a sample, but in the real world this is not the case i think. We come across any mobile and start communicating/sharing etc without having any prior knowledge of other person's IP. In such a case how to get the IP address of those who are using my application. How can i communicate without the prior knowledge of the IP address. How to implement this. Help me in sorting it. Thanks in advance.
EDIT:
And in case if the user connects the internet thro' GPRS/3G connection then his IP address will be changing based on the service provider. How can i find that.
Given what you are commenting on other answers, if what you want are the IP addresses of other Android devices to do some kind of P2P game you should note that there is no reliable way to do that directly.
If the users are connected in the same LAN you could provide in your application some kind of discovery service using UDP broadcasts.
If the users are connected to the internet and have public IP addresses then you could use some intermediate server to register the users at startup and have them discover other users using that server.
But (and this is the most common case) if the users are connected to the Internet and have private IP addresses (like when they are connected with WIFI on their LAN) you need some kind of server that acts as a proxy for their requests because there is no way to make a direct TCP connection from a natted IP to another natted IP. There are a few solutions to solve this problem, you could start for example by learning something about XMPP and how it works.
Your app must use DNS. You will first need get your IP into the DNS system. You do this by signing up for a domain name & setting up A / AAAA records for hostnames with a hosting provider (or you could set up your own DNS server). You may even find some free DNS providers.
In your app, you can hard-code a fully qualified domain name that you previously set up, say - app.foo.com and use the android gethostbyname library call to fetch the IP address for you. The local DNS resolver will then go to its DNS server and fetch the IP address corresponding to app.foo.com.
Can you use DNS? You can still hard-code the domain name if you want, and the domain name can be configured to point to any IP addresses anytime later.
I am trying to make an application which can connect from a mobile to a wifi controller. Planning to do a socket connection(multicast) ... The only values that i am able to get through the wifi android apis are SSID and BSSID.. Can anyone tell me if i am supposed to proceed with these values or am i supposed to connect with an IP address ? If i am supposed to connect with BSSID.. how do i go about it?
Wifi access points need not have an IP address, any more than wired switches and hubs do. However a large number do, as they also act on the IP layer as DHCP servers and network gateways.
What exactly are you trying to do? It sounds likely that it is not the Wifi access point proper that you need to talk to.
If it supports TCP and UDP, it will of course have an IP address. This will not be directly discoverable from the Wifi APIs, and you'll need some other means of discovering that. It's hard to say what exactly will be a reasonable method to do this without knowing what the AP is, and what services it provides.
Common ways of enumerating services provided on a network include DHCP; multicast DNS/DNS service discovery which is used by "Bonjour" and "Zeroconf"), SSDP and uPnP, and of course static configuration.
I'm not familiar enough with the Android network APIs to recommend anything, though http://jmdns.sourceforge.net/ appears to be a usable Java multicast DNS library.