Use TCP in Internet - android

I'am use TCP for connect my android phone with Windows 7 PC. When I'am send message phone-PC in LAN this system is work, as i`am use this system in Internet she is down because android app send me "time out". Why?
// The host name can either be a machine name, such as "java.sun.com", or a
// textual representation of its IP address
String host = "10.26.144.118";
int port = 20;
try {
Socket socket = new Socket(InetAddress.getByName(host), port);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
// true for auto flush
writer.println("Hello World");
myView.setText("Send hello world");
} catch (Exception e) {
System.out.println("Error" + e);
myView.setText("Error" + e);
}

You are probably looking for port-forwarding

Your problem is that you mixed up the LAN (local area network) with the WAN (wide area network) aka the internet. Your personal LAN is protected from outside.
You need a static public IP or a DDNS (Dynamic DNS) solution e.g. dyndns. Than you have to forward the traffic from your public IP to you internal Server IP. See also thax's answer.
Than can your smartphone connect to your static public ip or to your DDNS address. Than should your app also work with the mobile network.

Related

Send UDP from Android Emulator to Host PC

I'm trying to send UDP packets from an emulated device (Nexus S 4.0", 480 x 800: hdpi) to my host PC for development and testing. The sending side seems correct and doesn't encounter any errors, but Wireshark indicates they are not arriving at the host PC. I've researched this problem and all the fixes that worked for others are not working for me:
I added "uses-permission android:name="android.permission.INTERNET" to the maifest XML file. (I also have ACCESS_NETWORK_STATE but I don't think that's necessary for this.)
I am sending the packets to the host loopback address 10.0.2.2. The port is 5006, so it's not one that I should need special privileges for.
I am calling DatagramSocket.send() in a dedicated thread, not in the main thread. (I think this would throw NetworkOnMainThreadException anyway, and I'm not getting any exceptions.)
I have Telnet-ed into "localhost 5444" and issued the "redir add udp:5006:5006" command to setup UDP port forwarding on the emulator's virtual router. The command returns "OK" without error, and "redir list" returns "udp:5006 => 5006".
I've also setup UDP port forwarding (port 5006) on my host PC's router (between PC and open internet). But I don't think that should be necessary, this router is not between the emulator and the host PC.
I have disabled Windows firewall and anti-virus on the host PC.
Here is the relevant code in my MainActivity.java. The start() and stop() methods are called from button clicks (omitted because they are not part of the problem):
private static String TAG = "MainActivity";
private volatile boolean running = false;
private String ip = "10.0.2.2";
private int port = 5006;
public void start(View view) {
new Thread() {
public void run() {
byte[] bytes = "Hi from UDPSender!".getBytes();
try {
InetAddress inetAddr = InetAddress.getByName(ip);
running = true;
while (running == true) {
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, inetAddr, port);
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(false);
socket.send(packet);
socket.close();
Log.d(TAG, "Send packet to "+packet.getAddress().getHostAddress()+":"+packet.getPort());
Thread.sleep(1000);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
}
}.start();
}
public void stop(View view) {
running = false;
}

Device discovery in local network

I'm currently developing an android app using SDK >= 16 which should be able to discover different android devices (later also iOS devices) in a local area network using the WiFi radio.
My first guess was to use multicast which turned out to be non functional on my Samsung Galaxy S2: packets are only received when sent from the same device.
My second guess is to actively scan the network using a limited IP address range and wait for a proper response. Unfortunately, this implies that the network uses DHCP to address the IP addresses.
None of the above solutions seem to be the perfect solution.
My current solution for my first guess:
public class MulticastReceiver extends AsyncTask<Activity, Integer, String> {
private static final String host = "224.1.1.1";
private static final int port = 5007;
private static final String TAG = "MulticastReceiver";
protected String doInBackground(Activity... activities) {
WifiManager wm = (WifiManager)activities[0].getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wm.createMulticastLock("mydebuginfo");
multicastLock.acquire();
String message = "Nothing";
if (multicastLock.isHeld()) {
Log.i(TAG, "held multicast lock");
}
try {
InetAddress addr = InetAddress.getByName(host);
MulticastSocket socket = new MulticastSocket(port);
socket.setTimeToLive(4);
socket.setReuseAddress(true);
socket.joinGroup(addr);
byte[] buf = new byte[5];
DatagramPacket recv = new DatagramPacket(buf, buf.length, addr, port);
socket.receive(recv);
message = new String(recv.getData());
socket.leaveGroup(addr);
socket.close();
} catch (Exception e) {
message = "ERROR " + e.toString();
}
multicastLock.release();
return message;
}
}
This code results in blocking on line socket.receive(recv); If I specify a timeout, I get a timeout exception.
Check my answer in very similar question Android Network Discovery Service (ish) before API 14
I do not belive that multicast is not working on Galaxy S2, some time ago when I was coding some network application, I made several test on many devices, some older like G1 but also on S2, S3 and Galaxy Tab 10.
But to be able to use multicast you must enable it programatically.
Have you used this piece of code?
WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE );
if(wifi != null){
WifiManager.MulticastLock lock = wifi.createMulticastLock("Log_Tag");
lock.acquire();
}
Check out http://developer.android.com/training/connect-devices-wirelessly/index.html It mentions two ways of finding local services- NSD and wifi direct.

android chat between 2 phones using sockets

This is a bit long so I'll start with the question: how do I get the ip to link up sockets (not on a private network) on Android phone?
And how can I check if a port is being blocked by the phones ISP?
A bit more info:
I have a program that show users locations on a map and you can click on them and start a chat. I've tested the socket conntion and it was working fine on 2 emulators, but when I tried it on a phone it failed to link up the socket.
Out of time exception on the:
NotificationChat.ChatSocket = new Socket(serverAddr, 5000);
And my best guess is the IP of the server (aka phone 1) is not right, or maybe the port is blocked or in use.
I tried 2 ways to get the phone IP:
public static String getLocalIpAddress() {
try {
Socket socket = new Socket("www.google.com", 80);
Log.i("iptest", socket.getLocalAddress().toString().substring(1));
String ip=socket.getLocalAddress().toString().substring(1);
socket.close();
return ip;
} catch (Exception e) {
Log.i("", e.getMessage());
return "exception in get ip";
}
/*
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {
Log.e("b2264", ex.toString());
}
return null; */
}
IP I got was: 10.227.130.191
Which if i remember right is a class A local IP.
The server side:
while(flag==1)
{
if(ss==null)
{
try {
ss = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
Log.d("thread","chatnotifiction befor ss accpect");
Socket NotAvilabale=null;
NotAvilabale = ss.accept();
if(ChatSocket!=null)
{
Log.d("test55","not avilable");
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(NotAvilabale.getOutputStream())),true);
out.println("notav");
NotAvilabale.close();
continue;
}
ChatSocket=NotAvilabale;
Log.d("thread","chatnotifiction after ss accpect");
CharSequence contentText = "someone wants to talk to you";
PendingIntent contentIntent = PendingIntent.getActivity(this, 1, notificationIntent, 2);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(NOTIFI_ID, notification);
} catch (IOException e) {
Log.d("chat notifi io exception","chat notifi io exception ");
e.printStackTrace();
}catch (Exception e) {
Log.d("chat notifi Exception 2","chat notifi Exception 2 ");
// TODO: handle exception
}
}
I do not have much experience with sockets. This is the first time I am using them. I hope one of you has a bit more experience and can help me out.
Thanks in advance (sorry for the crape english).
So while I don't know much about how the cell infrastructures work, I can only imagine that it is similar to any ISP.
So imagine you are a large carrier with millions of clients. You can't give them all each their own reserved public IPs, that would be costly and inefficient. But you do have to give them IPs in order to send data to them. So you basically carve up your network into multiple segments. Each segment has complete network of private ips. Since most connections on phones are not peer to peer it would be safe to assume that all outbound traffic goes through a gateway or a set of gateways until it reaches a public gateway that will relay the message out to which ever public host is beng request. Whatever that gateway's IP is though, is probably what your server (and any server on the internet) would see as the client ip (which is probably not the same as the reported IP by the client). With all the devices acting this way, it would also be safe to assume that you can't just make a connection to 10.227.130.191 from a routable IP within the same network unless it has a port open, which in this case would probably mean running your software. I think physical proximity of phones may come into play on some level deciding as to which private segments two different phones get put it. However in most cases, it is not predictable enough to be able to say that Phone A at Lat1,Lng1 IP 10.127.x.x can talk to Phone B at Lat1,Lng1 IP 10.127.x.y simply because they do not have enough information to know if they are on the same physical segment of the network.
So unless you are on a wifi AP, it would be really really hard to allow a direct connections between the phones simply because the probability of them being on the same routable network would be very low.

How to get the system ip address after usb tethering of android phone?

I'm developing a mobile application in android.
Here I want to detect the IP address of the computer,system,etc after the usb tethering of the any android phone
I cannot find the solution.
If I put the following code then it takes the only the IP address of phone ,I need IP address of system
The following are code
ArrayList<InetAddress> arrayList=new ArrayList<InetAddress>();
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
arrayList.add(inetAddress);
inetAddress=null;
}
}
} catch (SocketException ex) {
Log.e("SALMAN", ex.toString());
}
return arrayList;
Please help me to get the system's IP address,If we cannot able to get means so please mention me. Because I'm new to android.
I'm using android 1.6 .
There is server side application in the windows xp system. That application is a windows service which is developed by C# .net.
That windows service listen to some port such like 234,etc.If some data comes to port then it will process the data and send response through that port.
In android the android application is send the data to the windows service via socket.
The android phone is USB tethered to the system in which windows service is running.Then system assume android phone is modem and additional IP address is generated for the system.This ip address is dynamically generated when the android phone is tethered.
For data transfer form mobile to system via socket .I will need to give the ip address of the system (after tethered) in my android coding.
If there is any method in android coding to get this IP address.
All are please give your ideas on regarding this.
Its not possible to find IP address created in PC from android after tethering. There is no API or other way to find it.
If you use InetAddress , it will return 192.168.42.129 - which is a DHCP address created by USB Tethering. It wont help you to communicate.
The other way is to scan the list of IP. USB Tethering will create ip ranging for 192.168.42.1 to 192.168.42.255 . You can write a simple scanner to find which one is active. But it will take some time.
Thanks to 'Swim N Swim' above. I found a code at
Retrieve IP and MAC addresses from /proc/net/arp (Android)
and modified a bit to get first IP having valid mac address. Works great when developing as a single user on your PC with tethered. You may follow above link for further selective IPs based on company name etc.
public static String getUSBThetheredIP() {
BufferedReader bufferedReader = null;
String ips="";
try {
bufferedReader = new BufferedReader(new FileReader("/proc/net/arp"));
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] splitted = line.split(" +");
if (splitted != null && splitted.length >= 4) {
String ip = splitted[0];
String mac = splitted[3];
if (mac.matches("..:..:..:..:..:..")) {
if (mac.matches("00:00:00:00:00:00")) {
//Log.d("DEBUG", "Wrong:" + mac + ":" + ip);
} else {
//Log.d("DEBUG", "Correct:" + mac + ":" + ip);
ips = ip;
break;
}
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return ips;
}
Note that each time you tether after untether, you must start your apache or other processes on PC to take new IP effective. THis is what I experienced.

android socket communication through internet

I'm experimenting with socket communication between android and windows.
Everything works fine till i use the 10.0.2.2 address which is the loopback to the computer on which the emulator is running. But if i give any other address to the Socket constructor the connection is timing out.
My goal is to communicate between my phone and my computer through the internet.
I also tried it on my phone, so i don't think that it's a firewall problem.
Here is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
clientSocket = new Socket("10.0.2.2", 48555);
Log.d("Offdroid", "socket connected");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.toString());
}
}
public void connectServer(View button) {
try {
String message = "shutdown";
byte[] messageBytes = message.getBytes("US-ASCII");
int messageByteCount = messageBytes.length;
byte[] messageSizeBytes = new byte[2];
messageSizeBytes = intToByteArray(messageByteCount);
byte[] sendBytes = concatenateArrays(messageSizeBytes, messageBytes);
Log.d("Offdroid", Integer.toString(messageSizeBytes.length));
clientSocket.setReceiveBufferSize(16);
clientSocket.setSendBufferSize(512);
OutputStream outStream = clientSocket.getOutputStream();
//InputStream inStream = clientSocket.getInputStream();
outStream.write(sendBytes, 0, sendBytes.length);
} catch(Exception EX) {
Log.e("Offdroid", EX.getMessage());
}
}
I'm also looking for a java built in function instead of the concatenateArrays function which simply put two byte array together.
Edit:
Sorry, maybe i not provided enough information. I have already tried my external ip used for the internet connection and my LAN ip. Port on router is forwarded to my computer. So if i write "192.168.1.101" or the ip given by the internet service provider in place of "10.0.2.2", than i cannot connect.
Edit:
Ok, i figured out it was my firewall.
Emulator takes uses the same network as that of your computer, so it will be able to route it to the computer. But for your phone to connect with your computer, you have to give a different IP, which is basically the IP of the computer.
I am guessing you are using some shared Network, and getting this (10.0.2.2) IP. Your computer should be directly connected to Internet in order for this to work from phone.
Ok, i figured out it was my firewall.
When you use a real Android phone as Internet Remote device, don't you have to set up your WiFi router, connected to your PC (or Android), for Port Forwarding? Then you give your Android Client the PC Server's External IP Address and the Server Port Number. Only then, provided the Port Forwarding works on the router, your remote Android Client (on SIM) can communicate with your PC Server connected to your router.

Categories

Resources