Android socket throws UnknownHostException error - java

Why do I get this error...
java.net.UnknownHostException: http://google.com
...when I do this in my Activity -> onCreate?
try {
Socket socket = new Socket("http://google.com", 80);
} catch(Exception e) {
Log.e(tag, e.toString());
return;
}
And yes, I do have the Internet permission set in my manifest.
<uses-permission android:name="android.permission.INTERNET" />
This is being tested on a physical Nexus S phone

Use www.google.com, without the http:// part.

Is it throwing an UnknownException or UnknownHostException?
UnknownHostException means there is a problem with the hostname lookup. Try it without the "http://" and if that doesn't work, try it with the direct IP address.
Its not your app permissions that is failing, otherwise it would throw a SecurityException.

Socket throws an
UnknownHostException - if the IP address of the host could not be determined.
Do you have Internet Access enabled? Try it with another host or with the IP and/or try restarting your phone.

Related

Server java app not working on a local connection

hi have at home a rasperry pi running a server java app, connected to de router with the dynamic DNS configured and the in/out communication ports openned.
When i run the android apication client througt 4g everithing is working sucessfull. But when i run the same app connected to the wifi on my local net, where the server are running, the server application looks like death.
Any ideas?
Thanks.
router config
I think the problem is related to your DNS. If you are connected using your wifi, you have to return a local IP-Address. Do you have any chance of configuring your router to return the raspberries local IP-Address for wifi-clients?
Take a look here: link
A simple solution, even if it is not very elegant, is adding the following conditions to your code:
If there is an error connecting to the Dyn DNS, try to connect to the local IP address. (In case you are in the Wifi LAN)
If the local IP address fails, try again your Dyn DNS (in case the user is a real user with real communication problems)
(repeat until the connection is successful)
You can also identify your testing devices (using Settings.Secure.ANDROID_ID, or the IMEI) and use the local IP only for them. Another option is making the URL configurable (with a hidden option for example).
Because of my app can run local, only needs to connect to server for updates. I have block the connection on the server app if the ip from client and server are equals.
At the moment is the best solution to keep the server app running properly.
URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new
InputStreamReader(whatismyip.openStream()));
String ip = in.readLine();
try {
SSLServerSocketFactory sslFactory = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLServerSocket ss = (SSLServerSocket) sslFactory.createServerSocket(PORT);
int idSession = 0;
while (true) {
SSLSocket socket = (SSLSocket)ss.accept();
if(socket.getInetAddress().getHostAddress().equals(ip)){
if (socket != null && !socket.isClosed()) {
socket.close();
}
}
((ServidorThread) new ServidorThread(socket, idSession)).start();
idSession++;
}
} catch (IOException ex) {
ex.printStackTrace(System.out);
Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
}
}

executing Socket(hostname,port) causes android to crash [duplicate]

This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 5 years ago.
Help! I'm trying to do some simple java socket networking in Android Studio and I can't even get in the door. The server program seems to be working ok but the android app client crashes with the error "Unfortunately InTouch has stopped" while executing the line:
sock = new Socket("Mark2015jun08", 4415);
where the hostname I put in is what is reported by the C:>hostname command, the windows Networking Control Panel and it shows up in the DHCP table when I log into the router. It even crashes when I put in "" for a hostname which the documentation says should open a loopback. I've tried calling Socket() a dozen different ways as you can see from my code below. I could sure use some help.
Thanks, -Mark
In the android client program I put the following try statement in the onResume() method:
try {
//sock = new Socket("Mark2015jun08", 4415);
byte[] ip = {(byte)192, (byte)168, (byte)1, (byte)124};
//sock = new Socket(InetAddress.getByAddress(ip), 4415);
//sock = new Socket(InetAddress.getByName("192.168.1.124"), 4415);
//sock = new Socket("LOCALHOST", 4415);
sock = new Socket("", 4415);
// ommitted logic to set socket timeout and
// open object streams based on sock
} catch (IOException e){
sock = null;
log(e.toString());
}
Both Windows ipconfig and the router DHCP table both confirm my ip address but I still get the same error. Three different sources all agree on my hostname but no matter what string I put in for hostname, even "", it doesn't work. What am I doing wrong?
I use the following permissions in my Manifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
This is my server program below created in Netbeans and I run it from the Windows cmd.exe window with the command C:>java -jar intouchserver.jar. This runs the server program on the laptop and it gets to the line
sock = serversock.accept();
and stops exactly as the documentation for accept() explains. As far as I can tell it's listening to port 4415. (Note: I checked serversock before this statement: it is non-null.)
package intouchserver;
import ...
public class InTouchServer {
private static ServerSocket serversock;
private static Socket sock;
public static void main(String[] args) {
try {
serversock = new ServerSocket(4415);
sock = serversock.accept();
} catch (IOException e){
System.out.println("Can't establish socket");
System.out.println(e);
System.exit(1);
}
// ommitted logic to open object streams based on sock
// and read and write to them
}
}
I solved my own problem. It turns out that if the Socket() call is in the onResume() function where I put it then you get a fairly useless error message but if you put the Socket() command in the onCreate() function you get a much more informative error: namely "NETWORK ON THE MAIN THREAD". So then putting the Socket() call in a thread solved the problem and off I went. THANK YOU so much James K Polk for the tip on logcat. I've been struggling with those "Application has Stopped" messages all along.

Socket writing java (android) to python

I want to create a super basic Android App that connects to a python server running on my PC but the python server never gets the connection
my java code:
public class WriteToSocket {
Socket sock;
public void Test() {
try {
this.sock = new Socket("PCName", 9871);
} catch (UnknownHostException e) {
System.out.println("Unknown host: PCName");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
}
public void Test1(){
try {
this.sock.close();
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
}
and
public void onClick(View v) {
WriteToSocket a = new WriteToSocket();
a.Test();
}
and my python server is
import socket
sock = socket.socket()
name = "PCName"
port = 9871
sock.bind((name,port))
sock.listen(1)
s,a = sock.accept()
I expected after the button click for the python server to accept the connection (I also tried changing "PCName" to "127.0.0.1")
I've looked around but nothing helped me so far :S
Bind your server socket to one of the IP addresses of your PC which is accessible from your android, and not to 127.0.0.1. Or alternatively bind it to all available interfaces (0.0.0.0).
Then connect from your android to that IP.
E.g. if your PC has IP address 1.2.3.4 then use this IP in both applications.
Use netstat to see if the port is really open on your PC.
Check to see if your android application has the permission to use the internet (specified in the manifest: "USES_INTERNET" or something like that).
Also your python script discards the connection as soon as it is made.
In python change bind address to 0.0.0.0. It will bind for all IPs attached to your machine. Then in android app change to correct IP of your computer.
IP 127.0.0.1 is a loopback and you can't connect to it from outside of the system.
The android phone doesn't know what PCName is, change "PCName" in the python code back to '127.0.0.1', then in the android project put in the local IP address of the server.
This of course assuming that both the phone and the server are on the same local network.

How do you catch an UnknownHostException in android?

I'm using HttpClient to post then retrieve something in Android, which works great, but when I dont have a internet connection it forces close, is their a way to catch UnknownHostException when making an HttpPost? I know I could make sure its connected to the internet before making the request, but what about if the phone just doesn't have service?
UnknownHostException is a Subclass of IOException, so you should be able to catch/manage it simply catching IOException or something more specific (NoRoute, ConnectTimeout, etc.)
Also consider adding connection check before doing network calls with ConnectivityManager
you can check for your intenet connection with
ConnectivityManager cm = (ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected() || cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
//connected
} else {
//not connected
}
And set the permissions in AndroidManifest
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Android HTTP Connection

Can anybody tell my why this doesn't work in the Android emulator? From the browser I have access and the server is internal. All I can think of is that I'm missing some configuration on my app so it can access the network layer.
try {
InetAddress server = Inet4Address.getByName("thehost");
//Doesn't work either
//or InetAddress server2 = Inet4Address.getByAddress(new String("192.168.1.30").getBytes());
if(server.isReachable(5000)){
Log.d(TAG, "Ping!");
}
Socket clientsocket = new Socket(server, 8080);
} catch (UnknownHostException e) {
Log.e(TAG, "Server Not Found");
} catch (IOException e) {
Log.e(TAG, "Couldn't open socket");
}
Throws an UnknownHostException
Thanks
As far as configuration goes, the only setting you should need to access the Internet from your application is the INTERNET permission, enabled by adding the following line outside the Application tags within your application Manifest.
<uses-permission android:name="android.permission.INTERNET" />
So the manifest would follow this general construction
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.apis">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name="MyApplication"
android:label="#string/application_title"
android:icon="#drawable/my_icon">
[ .. Your Activities go here ]
</application>
</manifest>
It might still not work, because of the timeout. Since you need root permissions to send an ICMP Package and the implemetation of isReachable will use the slow TCP version of ECHO. Chekcout the javaDoc.

Categories

Resources