I am implementing a mobile chat application, I am using socket connection for implementing p2p connectivity. My chat is working fine with android devices. My issue is I can connect a device in 3g network or with in the same WiFi network but the connection is not working when a device form outside WiFi try to connect a device in the WiFi network. I know it's because of the local IP of the device assigned by the WiFi. How can I root and connect a device in the WiFi?
Sounds more like a router settings issue, than an app issue (meaning that users of your app would need to do this for their own networks as well).
Your wifi router needs to know how to forward communication to your device. So say that your app is connecting on port 1234, then you need to tell your router to forward communication from the outside on port 1234 to the internal IP of your phone in your wifi network.
The phone that is outside of the network should target your network's external IP and port 1234.
Sajan, your issue is not only an IP mapping issue, but also a NAT traversal issue. It is not always possible to punch holes in NATs. And when it is, it must be done with some sophisticated techniques including a super peer located outside of your wifi/lan which will read the translated address from your inside peer.
Unless you are using UDP and the NAT is friendly, it is not possible to send TCP communication directly to the inside peer. In most case, you'll have to check what is possible with the NAT, and if there is something possible, you'll need to perform mapping prediction and tell both peer to attempt com on predicted IP addresses.
That's valid if you don't want you users to have to configure their NATs. And even in that case, such configuration will not always be enough (if there are cascades of NATs, or proxies for example).
Related
I have been trying to set up an app that allows communication between two devices, a server and a client. I have established the connection and can send messages between the two as long as they are connected to the same source of internet. When I connect the devices to two different sources, I am not able to establish a connection between the two. It works by entering the IP address of the server you want to connect to.
For example, if my server device is connected to my home Wi-Fi and my client device is connected to the same Wi-Fi router, communication works as supposed to. But, when I connect the server to Wi-Fi and my client to cellular data (or different Wi-Fi router), the client is not able to find the server.
From all the searching I've done, I found that it is because my server is bound to my local host. So my question is, How can I make my server reachable from anywhere regardless of what network you are connected to?
I used this tutorial to get my server running:
http://android-er.blogspot.com/2014/02/android-sercerclient-example-server.html
The very first comment is a question that asks why it only works on a local network and someone answered saying you have to set up port forwarding on your router. From what I understand, this will work only if the server device is always connected to the same router. This will not be the case for my app. The server will have a new IP address as the device changes networks. I want this IP address to always be reachable no matter what network the server is connected to.
You will need to create a relay server. This would be set up using a java application on the PC and it would manage virtual "rooms" that then relay the messages to the clients. The computer you run your relay server off of will need port forwarding but the clients will not. Much of the code from that tutorial could be applied to this concept.
See: How to create a java Server that accepts client connections and then build a relay connection for a client pair
If your server is behind a firewall, you will not be able to reach it unless that port is open on the firewall. The only way to avoid this is to have a non-firewalled server.
I have done this successfully before but I am not sure what is going on in this case.
Case that worked:
When I am at home and I connect my computer and my phone to same wifi such that they are on the same network. I can lookup the IP address of my computer and use that IP on my android app to talk to my computer. The local IP is something like 192.168.1.5.
However now I am using a public wifi router. When I connect my computer to wifi I get an IP like 10.10.77.162. When I try to use that IP in my android app to talk to my computer it fails everytime.
What am I doing wrong? Is there an easy way around this?
You have to make sure you forward the port you connect on from your router to your local computer inside your network. Similar to when you open ports for some games such as wow.
Connect your phone the same WiFi network.
Addresses in the 192.168.* and 10.* range aren't globally accessible. They're only used for local networks. If both devices are on the network, they can communicate with each other, but they can't if only one is.
Basically this was due to the fact that I was on a public network in which the router was outside of my control. The router was blocking traffic as one would expect.
Can i interact with a server(android device) from a client(android device) just to query a database located in the server using TCP sockets?
And Yes and No.
If your device is within wireless network and have own local IP. You can connect to it from client phone if it is in the same network just providing proper IP and Port.
If server phone is located in another wireless network, then Port have to be forwarder using router settings to the server port. Bear in mind that if you will reconnect to wireless network by phone, then IP will be automatically assigned by network infrastructure and it might be changed from previous.
If you want to connect to server phone when it is on 3G network (or similar non wifi), you wont have any specific IP, and it is not static, that way it will be almost impossible to create reliable network. It is more Peer-to-Peer model of network you are looking for.
It is much better if you use Server in the middle as Gateway, that way it will be reliable. The only thing is that you will have to host server and its processes with all traffic and so on.
I want to start a local network connection using the built-in Wi-Fi hotspot on Android devices.
Is there a way to accomplish it?
And how to communicate between two devices?
EDIT:
I want to do it programmatically. Then I can transfer my own data between devices.
I haven't done this before, so my answer is all theoretical.
I think what you need to do is declare one device the server and start its hotspot manually with a known name.
Start / stop built-in Wi-Fi / USB tethering from code? (According to this question, you can't start hotspot programatically).
Once you have the hotspot set up, you start up the server app and wait for incoming connections. The server app can show you the ip address or hostname.
On the clients, you can do a simple check and see if the hotspot name is around and automatically connect to it if you find it. See this link for connecting to a network:
Using WifiManager to connect to a network
As for your second question, how to communicate - you need to establish a connection between the devices. For this, you need the ip address of the server. The simplest thing to do would be to show the ip address on the server UI and then manually enter it on the clients and press connect. It would then establish a connection to the server on a known port and you can send messages between client and server.
For reference, I found NanoHttpd, which is a webserver for Android. It uses ServerSocket to listen for incoming connections.
Possible answers:
Before ICS and non rooted devices
There is no way you can connect to a device over wifi. There is no API to do. Bluetooth is your best option or user interaction.
Before ICS and rooted devices
I am not sure if someone hacked the code, but when I tried to do an automatic connection to a wifi spot I noticed:
The api is hidden inside the SDK.
The method that does the connection checks the thread who ask for it. If it's not the os thread, it throws an exception.
Using ICS
With ICS there is a new way to connect devices through wifi called Wi-Fi Direct.
Here is a link with some demos.
If you are going to develop your own application for each and every individual terminals(devices) then i think for you socket programming will do the trick .
Yes , android supports socket programming in the same was as java socket programming .
1st google java socket programming tutorials and then you can using the same knowledge in android .
Also do remember to include the uses internet permission in the manifest , actually thats something which ate my brains for a long time :)
You mean communication between wifi enabled devices without any server like p2p? if so its wifi direct which is supported in ICS check this out http://developer.android.com/reference/android/net/wifi/p2p/package-summary.html
Before ICS there is no standard android API for wifi direct, though Galaxy S2 has wifi direct it uses proprietary API's which 3rd party devs can't use.
i dont know programmically create wify LAN,but you can create wify LAN manually,then you can do java tcp/udp program as said by brianestey
"As for your second question, how to communicate - you need to establish a connection between the devices. For this, you need the ip address of the server. The simplest thing to do would be to show the ip address on the server UI and then manually enter it on the clients and press connect. It would then establish a connection to the server on a known port and you can send messages between client and server."
for manual connection follow the steps
take settings/wireless&networks/portable wi-fi hotspot settings from any one of the phone
create new hotspot and turn on wi-fi portable hotspot from there
connect all other device to that hotspot including your pc
you will get ip of each device programmically (includig pc,but i dont know)
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.