I am currently working on an Android app that needs to transmit data from one device to an other. I want to implement the data transmission without any server. I can handle the handshake to exchange the dynamic IPs on my own (Session Initiation) but I am struggling for weeks now how to send the data to the other device when knowing their public and private IP.
For now my app can just send data with TCP Sockets to devices within the same WiFi (so just using private IP). But they will get lost once I try to send to public IPs. Probably they can't pass the router's firewall. Turning off the firewall manually is no option. So I guess TCP is the wrong protocol. I think of something like "Voice over IP" but with sending any binary data instead of just video and audio.
My Ideas were:
something like Magic-Wormhole because it works like a charm on PC but unfortunately I did not find any way to use it in Android
RTP (Protocol used for Voice over IP)
"UDP hole punching" to handle the NAT.
One of those might be the solution. The problem is that I don't know how to implement such things in Java/Android
(my Project on GitHub)
Currently the internet is really complicated, basically you cannot reach another device by send data to its public IP because most PC or mobile device are behind a NAT.
What you need in such cases is a STUN server, the server can help two devices to communicate to each other in complicated networks. You can create your own STUN server by using open source implementation like STUNTMAN, but its really complicated, so my suggestion is just try a commercial STUN service.
You can check out the Google STUN server for RTP/UDP packet transmission to the network.
STUN servers: A Quick Start Guide
Port URI
STUN Server (Main LB) 19302 stun.l.google.com
STUN Server 19302 stun1.l.google.com
STUN Server 19302 stun2.l.google.com
STUN Server 19302 stun3.l.google.com
STUN Server 19302 stun4.l.google.com
Related
We are working on a Android project with the below requirements.
The application should be able to send data to all the devices which are running our application which exists in the WiFi LAN.
Some payloads are expected to be of size >= 5MB.
The data shouldn't be lost and if lost the client should know the failure.
All the devices should be able to communicate with all other. There will be no message targeted to a specific device instead all the messages should be reached all the devices in the N/W.
No internet hence no remote server.
Study we have done:-
UDP Broadcasting - UDP doesn't guarantee the message delivery but this is a prime requirement in our case. Hence not an option.
TCP - TCP guarantees the message delivery but requires the receiver IP address to be known before hand and in our case we need to send the message to all the devices inside the LAN. Hence not a straight option.
Solutions we are looking into:-
A Hybrid approach - Name one of the devices in the N/W as Server. Post all the messages to a local Server. The Server keeps a open socket to all the devices(which have our application) & when there is a message from a device then it routes the message to all the devices. The disadvantages of this approach are,
Server having multiple sockets open each per device. But in our case we are expecting devices <=5 in LAN.
Server discovery using continuous UDP broadcast.
We want to have all the data in all the devices. So if we newly introduce any device into the LAN then that device needs to get all the data from the server.
So my question, have you any time worked on these kind of hybrid approaches? Or can you suggest any other approaches?
Your hybrid approach is the way to go.
Cleanly split your problem into parts and solve them independently:
Discovery: Devices need to be able to discover the server, if there is any.
Select server: Decide which of your devices assumes the server role.
Server implementation: The server distributes all data to all devices and sends notifications as necessary. Push or pull with notifications does not matter.
Client implementation: Clients only talk to the server. The device which contains the server should also contain a normal client, potentially passing data to the server directly, but using the same abstract protocol.
You could use mDNS (aka Bonjour or zeroconf) for the discovery, but I would not even recommend that. It often createsmore problems than it solves, and it does not solve your 'I need one server' problem. I would suggest you handcraft a simple UDP broadcast protocol for the discovery, which already tells you who the server is, if there is any.
Select server: One approach is to use network meta data which you have anyway, for example 'use the device with the highest IP address'. This often works better than fancy arbitration algorithms. Once you established a server new devices would use this, rather than switching the server role.
Use UDP broadcast for the discovery, with manual heuristic repeats. No fancy logic, just make your protocol resilient against repeated packets and repeat your packets. (Your WLAN router may repeat your packets without your knowledge anyway.)
You may want to use two TCP connections per client, potentially to two different server ports, but that does not matter much: One control connection (always very responsive, no big amounts of data, just a few hundred bytes per message) and one data connection (for the bulk of the data, your > 5 MB chunks). This is so that everything stays responsive.
I'm working on a server-client project. I hosted server on Google app engine so there is no problem with IP there, all the clients can connect to the server easily. Yet the problem occurs when I try to connect to a client, which is quite complex because I don't have static IP for the clients. Can anyone suggest me a good way for server-client coomucication in this case, without requiring that clients must have static IP address?
Thank you very much.
Well, obviously the client should register itself with the server and update it's IP when it changes.
There is, for example, a program which does exactly that and then publishes the IP with a DNS.
But you should be aware that the IPv4 address space is not that big and a lot of internet clients do not own an IP (and work thru the ISP's NAT). If you have clients that do not own an IP then you might want to stick to the usual Pull: the clients should periodically issue a request to the server to check if there are new messages for them. With a Keep-Alive connection and an efficient server implementation the price of such checks might actually be low, although that kind of communication might not work very well with the GAE pricing.
I made application with java using socket. My computer is the server and my phone(android ) is the client. Only what i trying to do is to forward String from phone to client PC.
Everything works fine when i configure my router and open the port i using. i don't want every time when costumer will install my application will need to open port in the router.
I thought about using remote server that will run my server code. but i didn't find server that can do that . i don't want to make my pc a server for all costumers.
How does all the chats companies do it without open port?
You must look into UPnP. This is what /most/ if not /all/ torrent clients use to allow foreign connections, without forwarding ports. How chat clients do it is a different scenario. They use hacks such as firewall hole-punching using UDP (with an external server) http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html see this link for details on UDP hole punching.
Also see this article http://www.codeproject.com/Articles/13285/Using-UPnP-for-Programmatic-Port-Forwardings-and-N for usage of UPnP. But this is in C++, but I think you will understand.
EDIT: http://4thline.org/projects/cling/ I found this. I think it can help you.
You had to open port probably because of your routers firewall :). If you already opened let us say port 9090 then every client app (android phone) will be able to connect to it :). Of course if somebody wants to install server on their own pc they would problably forward some ports and disable some firewalls. If you want server with no special requriements lookup VPS'es. :)
I'm new to networking and was wondering a way to find out from an android phone java app whether there is an application running on any computer on a wifi network it's connected to and a point in the right direction on what to google or a tutorial?
edit: The application I'd be finding would have been made to be found by the android app
Thanks,
Harold
You should use a UDP broadcast. Basically, a server announces its presence periodically on a local network with broadcast packets. A client then picks up on these packets, finds the source and connects to it. A networking library like KryoNet (available for both J2SE and Android Java) makes it much easier.
InetAddress address = client.discoverHost(54777, 5000);
System.out.println(address);
usually application discover their peers in the same network using UDP broadcasts, maybe thats what you are looking for. this requires the app on the lan to listen on a specified port, the phone (or whoever is looking for that app) sends a udp packet to that port on the broadcast address (255.255.255.255), and the app replies with its individual ip address. not sure if that is what you are looking for and if its possible with android
I working on one project which Android device is act like a Server. I mean, when I send any requests to my device, then I will get a response.
If any one have any idea so please tell me. I am waiting for the reply.
A server usually accepts request on a certain IP and Port. This is a problem for mobile devices, because usually they're on a private network (behind a router) and one can not address IP and port of a special device.
So, practically spoken, I really doubt that a mobile device can act as a server.
A reliable solution would require some sort of extra proxy server. Basically your mobile will connect with this "ground-based" server and the system of proxy and handheld is the server you're looking for. It is operational once the handheld is connected. Client establish connection with the proxy and send their requests, the proxy forwards the request to the mobile device to get a service response for the client.
A nice architecture for this approach is XMPP, the implementation of the proxy server would be a standard xmpp server (like openfire).