I need to be able to discover the services on the local network (so say I am running a chat application and I want to discover other devices on local network running this chat), but sadly I need to be able to use it on devices with API < 16 (so I cannot use android.net.nsd) I am sure this can be done without using NSD API. Question is how. Any help?
There are at least three or four options.
You can use
TCP or UDP
Broadcast address
Multicast address
Iterate over all adresses in your network
HTTP
4 Make use of external server or something like GCM (Google Cloud Messaging)
ad.1 and 2
Pros:
+Easy to implement, server is sending predefined "hello" message on broadcast/multicast address of your subnet/network on specific port, client is listening on that port and when "hello" message arrives, he automatically knows server IP address (contained in packet)
+Connection to the Internet is not needed
Cons:
Some public networks blocks this addresses to avoid attacks (e.g flooding ).
ad 3.
Pros:
When Multicast and Broadcast is blocked what you can do is simply iterate over whole subnet. It is " brute force " method, but works, especially on typical home/small networks where mask is /24 - there are only 255 addresses to iterate through.
Connection to the Internet also is not needed
Cons
When mask is let say /16 it will take pretty much time to iterate all IPs
can cause battery drain
and will flood network.
ad. 4
Another approach is to make some external server that will be "orientation point" for devices. Each of them sends up its own Address, and looks if there are some entries from another devices from the same network.
Of course Internet connection is needed.
So, I think it is good idea to start with broadcast and multicast since it is very simply and will work in many places, but keep in mind that there are networks where it is not allowed to use.
Good reference can be found here http://docs.oracle.com/javase/tutorial/networking/datagrams/broadcasting.html
You should also check this one http://home.heeere.com/tech-androidjmdns.html
Related
just want to know is there any methods to allow 2 different apps to communicate. Both of the apps are installed on different devices as well. I had gone throught quite a lot of research, but seem that INTENT, BROADCAST RECEIVER failed to meet my scenario. INTENT, BROADCAST RECEIVER can be work if both of the apps installed on the same device.
Here i can say you can use to make your things work :-
Sockets are typically used to accomplish this between Android devices (or between any peer devices).
When two devices desire to interact, you configure one or both of them to "listen" for connections on a socket and accept a connection from the other when that happens (or you can have a dedicated client and server and the client always initiates the connections).
You can exchange messages after the link has been made.
Android client server socket applications come in a variety of forms, but one that I found handy was:
Example of Android Server/Client using Socket on the client side (and its companion server side blog article - link included in the client blog)
It should be noted that you might need to add your own "protocol" on top of this. For instance, if you are sending a file that is unknown in length without a special "end" character, you might want to add a byte (or several bytes to represent an int, long, etc.) at the beginning to indicate the length of the transmission so the receiving side can tell when it has received everything (or that it has not received everything in case of an error).
connecting via networks (such as most 3G/4G) that forbid inbound connections
Even though there is nothing theoretically blocking sockets from functioning in these situations, many mobile operators will not permit inbound socket connections in practise. You would also need to determine the mobile's public IP address, which is doable but adds complexity. Whether your solution will only ever operate on a single operator's network, you can test it out to see if it works; but, if it doesn't, you could discover that using a server in the "middle" is preferable and easier: Devices A and B establish connections with servers Device A "discovers" device B after requesting the addresses of connected devices from the server. Device A sends device B a message.
Actually, it indicates that the messages should be forwarded to device B while sending them to the server. Device B is informed by the server that a message is available for it (using some sort of message notification like Google Cloud Messaging for example, or simply by the devices polling regularly to see if they have any messages). Device B accesses the server and downloads the messages. The aforementioned will function on pretty much any network that permits internet connectivity. It does have the drawback of having a server, but for the majority of mobile networks, it is probably a necessary approach.
You make one app a server using ServerSocket.
You make the other app a client using a Socket.
With both devices in the same network the client can connect to the server knowing its local ip.
After connection established they can communicate.
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.
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.
I'm in the early stages of writing an app that will need to broadcast data to several other devices.
My first thought was using an UDP broadcast, however according to both
http://code.google.com/p/boxeeremote/wiki/AndroidUDP and
Android 3G UDP Broadcast
he UDP will not be able to push through the NAT when on the mobile network
(which is essential for my app).
I know that i could either use a server to broadcast however i'd rather avoid generating to much traffic on my home server.
The last alternative that i can think of is having several tcp/ip connections and looping through all connected clients and sending the broadcast. But since I'm counting on having at least 30 listeners I believe this will be to expensive.
I do not have any broadcast associated code yet, that's why I haven't posted any;)
Is there a way to break through the NAT? Will the phone be able to handle 30 simultaneous tcp/ip connections? Or should i look into some other method of broadcasting?
Any hint would be greatly appreciated!
Kind regards
Johan Risch
:::::::::::::::::::::::::ADDED::::::::::::::::::::::::::::::::
I will be sending strings of length 10-20 characters once every 30-360 seconds
(will be controllable by the user) containing geo points in string format. The order in which the data will be sent is not important, that's why I thought of udp first.
I've set up my server so that when a user logs in he/she updates my database with his/her current ip.
Preferably i'd like it to work globally, but as long as it would work within the mobile networks in the same country.
That's about all the relevant information i can think of, hope this clears some things up!
:::::::::::::::::::::::::/ADDED:::::::::::::::::::::::::::::::::
The NAT doesn't pass UDP through because UDP has no destination address, so technically UDP has to be sent to all subnetworks of the network. When the network is your home LAN, it's no big deal, but when the network is your ISP or university backbone or cellular provider, the UDP could be replicated to hundreds of thousands of subnets. That's a packet storm that will degrade network performance for everyone, and it's massive overkill for your particular app since you really only want to talk to a small number of clients.
This problem has been solved many times already. Instant Messaging clients have a similar situation as yours: want to do direct P2P messaging when possible, through firewalls. How do they do it? The original NAT traversal / firewall traversal solution was to set up a message relay server. All clients talk to the server, and the server echos messages from one client to the others as appropriate. It works with NATs and firewalls because the client initiates the outgoing connection to the server.
If the clients are able to establish a peer to peer connection, then the relay server can just give the clients each other's IP addresses and stop relaying messages.
UPNP is a protocol that enables clients to request a firewall to open a port for incoming traffic. BitTorrent clients use UPNP to enable clients to connect P2P for file sharing. Clients find each other via the torrent server. Most home LAN firewall routers support UPNP now, but it seems doubtful to me that a cellular network provider would provide UPNP support for over the air connections.
Another (remote) possibility is multicast TCP/IP, but as I recall this is really optimized for "push" content flowing from the server to clients rather than client-originated peer to peer.
Your best bet is to take a look at the open source IM clients out there, particularly ones with Android implementations, and see how they're doing IM. Jabber is one that comes to mind, I'm sure there are others. You could even use an IM system's messaging API as your data transport layer and more or less stay out of the wire level details completely.