I am trying to develop an Android (server) app that will accept TCP connections directly from the Internet. I tried this a couple of years ago with no joy. Is this even possible?
I asked this question differently way back then, on StackOverflow and elsewhere, and never got a satisfactory answer. The answers fell into two categories:
No, you can't
Most authoritative answer given: Most carriers won't route connection requests to mobile devices.
Yes, you can
These answers did not provide details or examples to help me.
What I Tried
I can successfully get my mobile device's external IP through various means. But this is only part of the puzzle. See Note 1 below.
I created a ServerSocket that listened on a port (e.g., 2000). But the app would not accept connections from the Internet on this socket. Apparently, this socket was listening on the local (internal) network of the device (i.e., 192.168.1.0).
I was able to connect from other apps on the device (which are on the same subnet).
I was also able to connect through a NAT router in my shop that translated Internet addresses to my device's local net. But this doesn't help me in the field (where no router is available). See Note 2 below.
I tried asking AT&T customer-support-type people but I don't think they understood my question.
Notes:
Yes, the device's IP address can vary with time or location, but I can always get the correct and current IP through various means (e,g., whatmyip.com, etc.). Nontheless using the current device IP doesn't work either. BTW - my public IP has never changed. Thus, for all intents and purposes, my IP is static. In any case, the IP issue is a well-flogged horse, I am fairly sure that this is a ROUTING issue, not an IP address issue.
I can connect via WiFi because my Internet modem/router offers DHCP connections on the back side via Wifi on the device's local subnet (192.168.1.). My device has address 192.168.1.65, therefore I can connect to it without ever going through my carrier.
AT&T tells me that I cannot buy a static IP for a mobile device (update 9/23/19).
My Current Theory (9/23/19)
It is my current humble belief that there is a NAT-like entity at play here. Either:
The public IP actually points to a NAT router at AT&T HQ.
The device has a built-in NAT-like router
In either case, under this theory, inbound TCP connections are not forwarded to the device's local net, but outbound connections pass through just fine.
Summary
Maybe the answer's still the same, but I thought I'd ask again in case things have changed or somebody's got some better insight nowadays,
It's true that you can't establish any TCP or UDP connection which is listening behind the main network (i.e. behind the NAT). Nowadays all the ISP allocate a private IP to every device (due to shortage of IP) connected to it hence creating a private network of devices behind NAT. (After the complete adoption of IPv6 the situation will change with every device becoming the part of main network)
Since NAT doesn't allow an inbound connection, the problem is solved using some of the NAT traversal technique such as:
Port forwarding
TCP/UDP Hole punching
In the Port forwarding process, we need to deal with the router setting which will forward the connection on a specific port to the same port on the internal network node. It is mainly used in gaming, VoIP, and p2p application.
In Hole punching technique (no need to deal with the router setting) we use an external server which is not behind any NAT to get the IP address (both public and private) of the devices which are behind NAT. Further, the two hosts create there own outbound session among each other in their respective NAT devices. Since the NAT devices allow the outbound session, the session is stored, and this same session is used for further two-way communication.
More information about Hole punching.
(UPDATED 9/26/19)
I am posting this "answer" not so much as an answer per se but rather to solicit constructive criticism and/or affirmation. Any statements I make below should definitely be implicitly prefixed by "I humbly believe that...".
Yesterday, I had a personal epiphany. I finally got it through my thick skull what some responders were saying. I present my new understanding below.
Heretofore I believed that AT&T's Mobile Data Network was just a direct extension to the Internet implemented with cell sites and trunk lines. Now I realize that it is a closed, private data transport mechanism. Since it is owned by AT&T, they can implement whatever protocols they choose to, including "private" data connections from their head-end to my registered phone. These connections are analogous to the LAN-side ports on a typical desktop NAT router. The head-end (i.e., their NAT router) is the only entity that can be accessed from the Internet.
The head-end connections between the Internet and my phone are over these AT&T-private connections. The "public IP" reported for my device (and, I believe, nearby devices) actually points to the AT&T head-end, in my case a 150 miles away in Miami). The head-end fowards outbound connections from my phone to the Internet, but does not forward inbound connection request.
About my "Public IP"
I believe that this doesn't exist and is, in fact, a meaningless concept. What would be the point of such an address if you cannot connect to it.
Summary
I now believe that the answer to my original question is "No way, Jose". This is not due to an addressing issue, but rather AT&T will not route incoming connections to devices. They also do not offer static IPs for devices over their private network (this wouldn't make much sense anyway given the above).
IF ANY STATEMENTS IN THIS PROTO-ANSWER ARE INCORRECT, PLEASE PLEASE LET ME KNOW WHICH ONE AND WHY IT IS INCORRECT
It depends on what type of IP your mobile phone provider assigns you
For your mobile device to accept TCP connections from the outside, it is only possible if your provider assigns you a public IP, but this is increasingly unlikely since given the shortage of available IPs many providers assign a private IP, like if your phone were inside a LAN, in this case your TCP port is unreachable from the outside.
Websites like whatsmyip tells you the public IP with which your provider finally connects you to the internet but it may be different from the one your provider assigns to your phone.
To know if you are in a private network install from Play Store an app called "PingTools Network Utilities".
When you start it you will see the IP of your phone, if it is different from the whatsmyip IP or is an IPV6 one that means that your provider assigns you a private IP, an unreachable one.
... always talking about connections through the cellular network and not through WiFi
Write a simple client for DynDNS or alike, in order to provide it with name resolution. Then you can serve pages with NanoHTP - or raw sockets. If you're behind a DSL router, you may need to read the external IP with TR-604 (unless DynDNS might eventually return the source IP) and setup a NAT port-forward for the incoming traffic on port :80. At home this is easier to setup than through UMTS, because some UMTS networks don't have public IP addresses, but may have private IP addresses.
I want to give a non - technical answer as I myself am not very proficient with network theory.
One thing is that Internetproviders usually expect extra cash if you want to run a server - hence the forced disconnects on consumer subscriptions like DSL(changing IP in the process).
Next thing is that establish a connection and send data out to a server is very unreliable on a mobile device. You can have android check if you have network. If it says no you don't need to try it - no means no. But yes doesn't mean a thing!
I write software for asset tracking using android. Usualy I want to send like one location per minute to that server. So I try to open a port. Android blocks on new Socket and it can go for like 2 Minutes until a timeout occurs even if I checked with ConnectivityManager right beforehand and it got me isConnected() == true.
And if I have a socket and even received something a second ago: I can write to that socket and get no error but get no answer, write again, no error no anser again and again.. And after like 2 minutes I get a whole bunch of errors in the log all at the same time.
When sitting in the bus visiting my mother is like driving through a 3rd world country judging by the internet connection. It might say 4g and 3 bars but chrome won't load page OR it says 2g and only 2 bars yet browser has no problems at all..
The whole android network-os (and I guess apple has to do it quite the same) is programmed more like: "here android I want to send this" and android saying "Ok" but thinking "I will send it as soon I feel fit to do so" :D
you need a static ip(public ip) address for that .
Mobile device ip address are not static so u cant .
To make it work .
Run a web server on a static ip & route the queries to your app (tunnelling).
When android app starts ,you android app needs to register with web server .
Now server knows your android device availablity ,the queries from other end will be be rediredcted.
Related
I am a freelance systems administrator and architech. I have two small simple android apps that communicate with each other... One is a "server" that receives commands and the other is a "client" that sends the commands... Example: the client connects to the servers IP:Port and sends: "PC1 WAKEUP" The server executes wake on lan for PC1. Or the client sends "PC1 ls -la" and i receive the file list on the client... It works in my local network with wifi and i have configured port forwarding to access the server (an old android phone always connected to my wifi) from my phone anywhere as long as both have internet connection... And this is my problem... My home internet connection has many down periods and breaks... GSM does not...
So i want to do the same using GSM, CDMA or a direct data connection using a data call. I want to establish a data connection between the two android phones. In a similar way to connecting two PC using modems. One dials the number, the other is waiting and picks up the call and they communicate...
I have been trying to find a way to do this and i even learnd a little about XMPP and google talk but it seams to be outdated... It seams to be possible by exchanging SMSs but is not as functional and can be very expensive (and slow) for long sets of commands... I have a number of equipments at home that i need to interact with... in a fast way... I am lost here... Is this even possible? I cant find a way to do this... Any help is welcome... Even if i am looking at this the wrong way... New ideas are also welcome...
Thanks
If they're on the same wlan connection, you can do WifiDirect. Or traditional networking. If not- writing a server to run on a mobile phone is next to impossible. IPs change too frequently to keep DNS up to date, and cell networks are firewalled. You're just not going to have any reliable way to connect to a phone without a central server of some sort. You can try hacks like SMS, but remember that SMS is unreliable- messages may be dropped, or delivered days later (I just lost my phone, when I got the new one a week later I got several days worth of SMS at once- all of them with a timestamp of right now). You need a central server.
Can anyone point me to any sample code which explains (even slightly) how to write a simple wifi speedtest program for Android? I have looked everywhere!
Thanks in advance!
-Michael
It's not easy. Let me give you some suggestions but you will need to investigate more.
I'm not sure whether it is possible to access low level metrics of the WiFi connection or a 3G connection. Supposing it's not possible, my suggestions are oriented to use a ping or a ping-similar solution with some server and obtain the round-trip time (RTT).
Now, when you connect to a server, there are many factors affecting the RTT, these are the main ones:
WiFi speed, congestion, and communication errors
Latency in the whole path to the server, including ISP capacity and backbones.
Congestion in the path
Server speed to respond
Usually you execute a ping to test reachability and a taste of RTT. Ping is implemented with ICMP Echo Request. However, Java does not provide the means to send an ICMP message. So you might try to establish a TCP connection to some server.
You could use InetAddress::isReachable with a timeout various times until you find out the limit timeout. I wouldn't recommend this.
http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#isReachable(int)
I would create a TCP socket and call connect and then determine the time it took since connect was called. Of course you have to deal with all factors that affect speed.
Another point to consider is that if you use connect in a TCP socket, you have to understand that there is actually a three-way handshake: client sends a SYNC, server sends SYN/ACK, client sends ACK. But this last ACK doesn't add significant time to the return of connect because it's just sent by the client.
Having said that, I'll go with some suggestions:
First thing I would try, only with a WiFi, is trying to establish a connection to the access point, to port 80, 8080 or 443. That would eliminate other the last three factors.
If it doesn't work you could try a fix server, www.google.com for example. In this case you will have to deal with all the mentioned factors.
In the case of 3G, I don't know how you could could establish a connection to the access point like a Gateway GPRS Support Node in UMTS. But you can connect to a fix server, considering all 4 factors mentioned above.
Other point to consider si that when the smartphone has connectivity to WiFi and Cellular, it always uses WiFi. There are ways to force it to use 3g though, some links:
Android: Force data to be sent over radio vs WiFi
Force Android to use 3G when on local area wifi without net access
I hope this helps.
I have a simple app idea in my mind and I need to know how to connect from an Android application (client) to a Windows application (Delphi, server).
There is no need to be specific about the platform, I am familiar with networks in Delphi using winsock or Indy and I'm sure I will be able to figure out the appropriate mechanism in Android.
What I need to know is how to connect to a server (computer), which doesn't have its own public IP and is not in the same network as the client (one can be behind a local router, while the other might be connecting to the internet through 3G, for instance). This should be possible, as many programs work like that (remote desktop programs, TeamViewer, for instance: one computer is assigned an ID and using this ID other computer can connect to it.) I will not have access to the routers behind which the app will be running, so port forwarding is not an option.
I have a working network app, but that only works in LAN, so I'm guessing somewhat another approach is needed.
Thanks for answers
Many of the programs that work that way still use a server with a public IP. Each side of the client connections to the server to say "here I am". The public server can then shuffle data between the two clients.
That still leaves a lot of questions regarding the communication between the public server and each client - i.e. pull vs. push for taking data that was sent to the server and getting it back down to the second client.
You may want to read the specification for Copilot (originally named Project Aardvark). Joel Spolsky published the specification when the started the project. It talks about their use of a reflector service.
The Reflector
A Windows Service which we run on our servers, used to
allow any helper to help any victim even when both of them are behind
firewalls. Both helper and victim connect to the reflector. The
reflector checks that they are authorized and relays messages between
helper and victim until the paid-up time runs out
you could put an intermediate server which they can both route for "nat traversal".
otherwise you will have to put port forwarding on one of those computer's local router to allow incoming connections to be forwarded to the computer.
I need to make a peer-to-peer connection between two android phones running i-jetty web server through gprs channel.But many mobile operators block the inbound connections to the phones.Is there any way around it?
NAT penetration is complex enough that you really shouldn't mess with it until you're quite familiar with the internals of networking. The autonomous NAT traversal used by pwnat is pretty much the state of the art these days.
The basic idea is to use the fact that a router might have any IP address and as far as a NAT knows, any source IP address is valid for an ICMP error message, which the NAT will forward to its client.
Note that you can usually only get UDP through. So you'll have to implement your own byte-stream protocol.
In general, the most reliable way of getting two phones talking to each other is using C2DM (or GCM, now). Perhaps you can have the devices exchange their IP addresses using C2DM (which may get you nothing at all, btw, if its an address behind a router or firewall with blocked ports). You could also use SMS depending on the needs of your apps.
Usually there'd be a server of yours involved--additional development--but for short messages, I don't see why one device cannot directly post via C2DM to another device. (This is an untested statement, beware.)
Actually i am developing tracking app and want to send Location updates between two Android phones so that both can track one another over the Map. My application must get real time updates from other android device for better tracking.
I Have searched couple of techniques but don't know which one is best
Using Sockets: making one device as Server while other as Client
Possible Limitation:
What if IP address of Server is changed (because WIFI don't have a
static IP)
Cannot access if the IP address of server is private
Only client can connect to Server and Server cannot connect to Client
Using Intermediate Server: create an intermediate server and make a communication via that server.
Possible Limitation:
Slow because each Android device first send these updates to server
and then server push these updates to other android device
Please provide me your suggestion about which one is the best way to do this.
Since you didn't state the Device API level you want to support I'll provide you with an option for Android v4 (API level 14) devices. It's called Wi-Fi Direct and allows p2p connections between phones. It's essentially your socket approach, but allows easy neighbour discovery and allows transfers in both directions.
Well wifi is out.. Not for your stated purpose at least. Unless your map is quite small. Wifi is for say 100 meters (on a really good day)
Not knowing as much about android as I do of other mobiles, I'd say you're in for some pain.
I'd suspect connecting to your phone with a peer to peer might be a real slog.. some providers won't let it happen.
I have an approach more than an answer..
From an android phone, see if you can get your ip address.
From a desk, ping that ip address.
If it works, you're well on your way..
Id even say given the size of your info, you could use pinging as your main data carrier.
Pings can contain more than just random bytes. You could include an ID, and GPS in the contents you send in your ping. --- perhaps include a check sum ---
Do most of the work desk to phone, because development would be faster.. Then when your phone is capable of catching the pings.. Well then sending the ping should be easy as.