I'm currently writing a small test Android app, and have run across a small (large) problem with the emulator.
The code that goes out and scans the local subnet for computers running my server piece of the software does not return anything! This code functions perfectly on the desktop portion, so I know something is wrong inside of my emulator.
I had to hardcode the IP scan first because I cannot determine the IP address within the emulator, so I know I'm at least scanning the right range.
Summary: How can I connect to servers via sockets from inside my emulator on the local subnet?
Thanks all!
Here's the requested code:
public static ArrayList<String> serviceScanner() {
ArrayList<String> servers = new ArrayList<String>();
// Get the IP of the local machine
String iIPv4 = "";
String test = "";
//getLocalIpAddress();
//System.out.println(test);
try {
// Get localhost
InetAddress addr = InetAddress.getLocalHost();
// Get IP Address
byte[] ipAddr = addr.getAddress();
iIPv4 = addr.toString();
iIPv4 = iIPv4.substring(iIPv4.indexOf("/") + 1);
iIPv4 = "10.0.2.1";
} catch (UnknownHostException e) {
// Exception output
}
// IP stuff.
String IPv4Start = "", IPv4End = "";
iIPv4 = iIPv4.substring(0, iIPv4.lastIndexOf("."));
iIPv4 += ".";
IPv4Start = iIPv4 + "1";
IPv4End = iIPv4 + "254";
PrintWriter out = null;
BufferedReader in = null;
// Loop to scan each address on the local subnet
for (int i = 1; i < 255; i++) {
try {
System.out.println(iIPv4+i);
Socket mySocket = new Socket();
SocketAddress address = new InetSocketAddress(iIPv4 + i, port);
mySocket.connect(address, 5);
out = new PrintWriter(mySocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
mySocket.getInputStream()));
out.println("Scanning!");
String fromServer;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Server here!")) {
servers.add(iIPv4 + i);
mySocket.close();
break;
}
}
mySocket.close();
out.close();
in.close();
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
return servers;
}
}
The emulator is not on the same subnet as your computer. It's on it's own virtual subnet connected to the computer via its own NAT router. There is an explanation here: http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking
However, the emulator, via its router, should be able to connect to any socket anywhere on the Internet. What is the address you are trying to connect to? The emulator won't route 10.0.0.0 private addresses because it uses them for itself. Not sure about 168.192.0.0. Can you post the code that is failing?
Related
I am new to android and Java. And I am trying to learn android app development from UDACITY. I was trying to run this code and I am expecting a SocketTimeOutExcepetion but what I am getting is UnknownHostException.
try {
final String BASE_URL = "http://api.openweathermap.org/data/2.5/forecast/daily?";
final String ZIP = "zip";
final String MODE = "mode";
final String UNITS = "units";
final String COUNT = "cnt";
final String APP_ID = "appid";
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter(ZIP, params[0] + ",in")
.appendQueryParameter(MODE,format)
.appendQueryParameter(UNITS, units)
.appendQueryParameter(COUNT, Integer.toString(numDays))
.appendQueryParameter(APP_ID, BuildConfig.OPEN_WEATHER_MAP_API_KEY)
.build();
String str = java.net.URLDecoder.decode(builtUri.toString());
URL url = new URL(str);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(5000);
urlConnection.setReadTimeout(5000);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null)
buffer.append(line + "/n");
if (buffer.length() == 0)
return null;
forecastJsonStr = buffer.toString();
Log.v(LOG_TAG,"JSON forcast string:" +forecastJsonStr);
}catch(SocketTimeoutException e) {
startActivity(new Intent(getActivity(),CheckNet.class));
} catch (IOException e) {
Log.e("FetchWeatherTask", "Error:" + e.toString());
return null;
}
I tested it on my phone running Android version 4.0.4. And while testing I had my mobile data and wifi off
When your mobile data and wifi are turned off, the socket layer is unable to resolve internet addresses (e.g. "openweathermap.org") into an IP address. This is why you get an UnknownHostException.
Whereas, when you're on a network, and it's able to resolve IP addresses, and the server fails to reply, you will get a SocketTimeoutException.
If you want to simulate the exception do the following:
Disconnect your data and connect your Wi-Fi
Edit your setting of your Wi-Fi connection
Change to static IP and put 169.254.0.50 for IP, 255.255.0.0 for subnet and 169.254.0.1 for gateway
Change the BASE_URL = "192.241.169.168/data/2.5/forecast/daily?"
Run your app
I'm trying to build a software that checks what devices are connected to my home network and return a list of those device's MAC address every 10 minutes or so.
My approach was to ping all of the possible IP addresses on the network and call "arp -a" afterwards.
The following code works to find if a device is registered on an IP address, but I don't know how to get the MAC address from this.
try {
String currentIP = InetAddress.getLocalHost().toString();
String subnet = getSubnet(currentIP);
System.out.println("subnet: " + subnet);
for (int i=1;i<254;i++){
String host = subnet + i;
System.out.println("Checking :" + host);
if (InetAddress.getByName(host).isReachable(timeout)){
System.out.println(host + " is reachable");
try {
Socket connected = new Socket(subnet, port);
}
catch (Exception s) {
System.out.println(s);
}
}
}
}
catch(Exception e){
System.out.println(e);
}
Any suggestions?
You're blindly assuming IPV4, which is not so reasonable anymore these days.
And you're trying to dig out information that routers and access points have no good reason for disclosing in the first place (at least not to robots who won't authenticate themselves as an admin with access rights to the router's or access point's admin page).
Try this one.
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
public class App{
public static void main(String[] args){
InetAddress ip;
try {
ip = InetAddress.getLocalHost();
System.out.println("Current IP address : " + ip.getHostAddress());
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
byte[] mac = network.getHardwareAddress();
System.out.print("Current MAC address : ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
System.out.println(sb.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e){
e.printStackTrace();
}
}
}
This NetworkInterfaceNetworkInterface.getHardwareAddress() method is only allowed to access localhost MAC address, not remote host MAC address.
Note : You can't do this in remotely for PC or Device in java.But you can do it by using C# and WMI - WMI with netowrk in .NET language
I am trying to implement a server/clint java application. Once the server socket is listening on port 3232, I would like to client to automatically browse the network and scan each IP address in the subnet till it finds another instance (server) that is running on port 3232 and then report it's IP address so I can use it in the application to set as the socket connection destination IP address.
I have been suggested to use exec(nmap) to scan the network for the open port but I want to deploy this application on systems where do not have nmap installed.
If I understand correctly, I have to make a for loop to iterate through the host to finally find the right host whose port 3232 is open.
public static ArrayList<InetAddress> checkHosts(int socket, int timeout)
{
ArrayList<InetAddress> al = new ArrayList<InetAddress>();
try
{
byte[] buffer = {1};
DatagramSocket ds = new DatagramSocket(socket);
ds.setSoTimeout(timeout);
DatagramPacket dp;
InetAddress local = InetAddress.getLocalHost();
String subnet = getSubnet(local);
System.out.println(subnet);
for(int i = 1; i <= 255; i++)
{
String host = subnet + i;
try {
ds.send(new DatagramPacket(buffer, 1, InetAddress.getByName(host), 3232));
ds.receive(dp = new DatagramPacket(buffer, 1));
if(dp.getPort() == socket && !dp.getAddress().equals(local))
al.add(dp.getAddress());
} catch(Exception e) {
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return al;
}
I have a java program which accepts a http request from web browser and in response, program sends a text file contents to display in web browser. The program is working fine when I make request from browser which is installed on the same machine in which java code is running but when I make request from some other web browser which is not on the same machine as in which java code running, the program does not get any request.
This is how I make request from my web browser:-
http://localhost:port_number/
This is working fine...
This is how I make request from some other web browser which is not on my machine:
http://my_ip_address:port_number/
This is not working...
And this is my java code:-
while (true) {
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
serverSocket = new ServerSocket(32768);
clientSocket = serverSocket.accept();
InetAddress ia = clientSocket.getInetAddress();
jTextArea1.append("Connected to : " + ia + "\n");
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
String inputLine, outputLine;
String s = (String) JOptionPane.showInputDialog(this, "Enter File Name : ");
File f = new File(s);
if (f.exists()) {
out.println("http/1.1 200 ok\r");
out.println("Mime version 1.1");
out.println("Content-Type: text/html\r");
out.println("Content-Length: " + f.length() + "\r");
out.println("\r");
BufferedReader d = new BufferedReader(new FileReader(s));
String line = " ", a;
while ((a = d.readLine()) != null) {
line = line + a;
}
out.write(line);
out.flush();
jTextArea1.append("File Delivered.\n");
d.close();
}
out.close();
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
jTextArea1.append("Accept failed.");
System.exit(1);
}
}
This is not related to the code that you've written. You need to make your IP address publicly accessible. Here's is a related thread.
Check that you are indeed listening on 0.0.0.0:32768 and not 127.0.0.1:32768 or any other particulat IP (specially if you are connected to several network). Start a shell and use netstat -ano on Windows and netstat -anp on Unix or Mac.
Check that your firewall allows remote connection to the port 32768
I'm creating a very simple Java chat program, using the Java TCP sockets. I'm new to socket programming and Java. I cannot connect with server, because every time the client connects to server it times out. Maybe, it is because I'm typing the wrong IP address——I don't know.
Here is the code for the Server:
try
{
int fport = Integer.valueOf(port.getText());
ServerSocket server = new ServerSocket(fport);
Socket socket = server.accept();
msg.append("\\n Server is listening to port:" + port.getText());
BufferedReader input = new BufferedReader( new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.print(msgtxt.getText());
msg.append("\n\n" + input.readLine());
msg.append("\n\n" + Nombre.getText() + msgtxt.getText());
}
catch (Exception ex)
{
msg.setText("\n\n" + "Error:" + ex.getMessage());
}
Here is the code for the Client:
try
{
int iport = Integer.valueOf(port.getText());
int i1;
int i2;
int i3;
int i4;
i1 = Integer.valueOf(ip.getText());
i2 = Integer.valueOf(ip1.getText());
i3 = Integer.valueOf(ip2.getText());
i4 = Integer.valueOf(ip3.getText());
byte[] b = new byte[] {(byte)i1, (byte)i2, (byte)i3, (byte)i4 };
InetAddress ipaddr = InetAddress.getByAddress(b);
Socket sock = new Socket(ipaddr, iport);
BufferedReader input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
output.write(m.getText());
while(!input.ready()){}
msg.setText("\n\n" + input.readLine());
msg.setText("\n\n" + m.getText());
output.close();
input.close();
}
catch (Exception ex)
{
msg.setText("\n\n" + "Error: " + ex.getMessage());
}
verify that you can connect to the server using telnet (on windows you may need to install it as it's not installed by default anymore).
basically, open a connection to your server and see that it works:
telnet host port
if it works, maybe the problem is not in establising the connection but in waiting for a response from the server (add the exception to your question).
one note:
you can open a socket without creating the INetAddress as you did, just new Socket(hostname, port).