How can I check whether my computer is connected to the Internet. I don't want to use URL check method. Is it possible to call an operating system's function using java? For example, in JNA library, is there any function to perform this ?
You can use ping command like this:
class PingHost
{
public static void main(String[] args)
{
String ip = "www.google.com";
String pingResult = "";
String pingCmd = "ping " + ip;
try
{
Runtime r = Runtime.getRuntime();
Process p = r.exec(pingCmd);
BufferedReader in = new BufferedReader(new
InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
System.out.println(inputLine);
pingResult += inputLine;
}
in.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
You should receive a response like:
64 bytes from 173.194.37.147: icmp_seq=0 ttl=52 time=299.032 ms
64 bytes from 173.194.37.147: icmp_seq=1 ttl=52 time=508.100 ms
You could check to see if a common hostname (such as google) is resolvable through dns to an ip address.
Once that address has been resolved, you can check to see if it is reachable.
Related
I want to get CPU ram free space with java for many server
any idea.
Well depending on target platform there are multiple ways:
Have java clients running on each system that will collect this information on request and then have a server that collect and display all this information. This is most platform independent solution but require you to write client and server and install clients on each system.
If SSH is supported on platforms, you can using Java program to login to each system and use command line utilities to query resource. This however require you to either have credentials for each system or the SSH keys available.
Use NET-SNMP on target platforms if supported and enable resource collection. Java program can then query the SNMP agent to collect resource usage. You would require a library to talk with SNMP agents. You can SNMP4J or AdventNet for this purpose.
Im just a Trainee but my solution would be to Write a Server socket and run it on the servers.
Than open a connection over a Client socket and ask for information.
Than i would simpel return the Used Mb or simple convert it to a % Value.
Anyway i would prefer to use a existing and tested solution.
EDIT:
Here a Tutorial on how to get your free , Max and Used RAM.
http://crunchify.com/java-runtime-get-free-used-and-total-memory-in-java/
EDIT2:
Here the code of my Idear:
Server Part:
public static void main(String[] args) {
try {
ServerSocket sSocket = new ServerSocket(6969);
Socket socket = sSocket.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
String str1 = "";
//Add Varaibles you want to return
double ram = 15.0;
while (!str1.equals("stop")) {
str1=dis.readUTF();
//Return Value you need by param
if (str1.equals("getRam")) {
//Add Your calculation here
dout.writeUTF(String.valueOf(ram));
dout.flush();
}
else if(str1.equals("stop")){
dout.writeUTF("stop");
dout.flush();
}
else {
dout.writeUTF("Unknown Command");
dout.flush();
}
}
sSocket.close();
socket.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client part:
public class Main {
public static void main(String[] args) {
try {
String serverIp = "localhost";
Socket socket = new Socket(serverIp, 6969);
DataInputStream dIn = new DataInputStream(socket.getInputStream());
DataOutputStream dOut= new DataOutputStream(socket.getOutputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = "";
String str2 = "";
dOut.writeUTF("getRam");
//for manual param transmitting
//str = br.readLine();
//dOut.writeUTF(str);
dOut.flush();
str2=dIn.readUTF();
System.out.println("Server response:" + str2);
br.readLine();
} catch (UnknownHostException e) {
e.printStackTrace();
System.out.println(e);
} catch (IOException e) {
e.printStackTrace();
System.out.println(e);
}
}
}
I hope that helps you.
Anyway i dont think you can get data without connecting or have a connection to your server.
I'd like to map a port number to a user (linux user that is running a process that is binding to the port).
How can I do it in java?
I know I can go out to the shell and run bash commands that map a port to a PID, and then PID to user, but I'd like to keep it inside java if I can.
The more general question is: I have a webapp application that receives requests from localhost, and I'd like to know which local user performed the HttpServletRequest, so I can attach proper authorities to it.
Background:
I'm using spring security for all remote connections. However, I have a small part of the application (separated from the webapp) that is running locally alongside the application server, and that application is authenticated using the linux user mechanism. So for that reason, I bypass the server authentication rules for localhost (assuming all localhost access is permitted). The problem is with authorization - I need the identify the user running the localhost requests. Any idea how can I achieve this?
This is Linux dependent code, but not difficult to port to Windows.
This is not a Servlet code, but would work in that case as well:
Lets say I've a ServerSocket waiting on accept() call. When it receives a client request, it creates a Socket at another port to deal with that 'remote' request.
ServerSocket ss = new ServerSocket(2000);
System.out.println("Listening on local port : " + ss.getLocalPort());
while(...)
{
Socket s = ss.accept();
System.out.println("accepted client request, opened local port : " + s.getPort());
...
}
So, you need to feed the output of s.getPort() from above snippet to the following program's main() method.
public class FindUserByPort
{
public static void main(String[] args) throws Exception
{
String cmd = "netstat -anp | grep ";
int port = Integer.valueOf(args[0]);
cmd = cmd + port ;
Process pr = Runtime.getRuntime().exec(cmd);
InputStream is = pr.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
List<Integer> pIDs = new ArrayList<Integer>();
while ((line = br.readLine()) != null)
{
if (line.contains("127.0.0.1:" + port))
{
String pidPname = line.substring(line.indexOf("ESTABLISHED") + "ESTABLISHED".length());
pidPname = pidPname.trim();
String pid = pidPname.split("/")[0];
pIDs.add(Integer.valueOf(pid));
}
}
if (pIDs.size() > 0)
{
for (int pid : pIDs)
{
String command = "top -n1 -b -p " + pid ;
Process p = Runtime.getRuntime().exec(command);
InputStream _is = p.getInputStream();
BufferedReader _br = new BufferedReader(new InputStreamReader(_is));
String _line = null;
while ((_line = _br.readLine()) != null)
{
_line = _line.trim();
if(_line.startsWith(String.valueOf(pid)))
{
String[] values = _line.split(" ");
System.out.println("pid : " + pid + ", user : " + values[1]);
}
}
_is.close();
_br.close();
}
}
is.close();
br.close();
}
}
I am implementing a Java method that measures a number of metrics while loading a webpage. The metrics include : resolve time, the connect time and download time.
The challenge seems to be the name resolution, since the code should never trigger two NS look-ups by any means (even when DNS caching is disabled).
My first thought was to trigger the name resolution before connecting to the server, and then prevent java from running a second one upon connect.
Using InetAddress.getByName() for the name lookup and then HttpURLConnection and it's setRequestProperty method to set the a host header seemed to do the trick.
So here is my question: Do those two snippets below have the same effect? Do they always give the exact same result for all possible hosts? If not, what other options do I have?
VERSION 1: Implicit name resolution
/**
* Site content download Test
*
* #throws IOException
*/
public static void testMethod() throws IOException {
String protocol = "http";
String host = "stackoverflow.com";
String file = "/";
// create a URL object
URL url = new URL(protocol, host, file);
// create the connection object
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// connect
conn.connect();
// create a stream reader
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
// read contents and print on std out
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
// close the stream
in.close();
}
VERSION 2: Explicit name resolution
/**
* Enhanced Site content download Test
*
* #throws IOException
*/
public static void testMethod2() throws IOException {
String protocol = "http";
String host = "stackoverflow.com";
String file = "/";
// Do a name lookup.
// If a literal IP address is supplied, only the validity of the address format is checked.
InetAddress address = InetAddress.getByName(host);
// create a URL object
URL url = new URL(protocol, address.getHostAddress(), file);
// create the connection object
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// allow overriding Host and other restricted headers
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
// set the host header
conn.setRequestProperty("Host", host);
// connect
conn.connect();
// create a stream reader
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
// read contents and print on std out
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
// close the stream
in.close();
}
TIA for the help.
-Dimi
I've browsed through Java's source code to see what happens when you pass a domain name to HttpURLConnection and it eventually ends up in NetworkClient.doConnect:
if (connectTimeout >= 0) {
s.connect(new InetSocketAddress(server, port), connectTimeout);
} else {
if (defaultConnectTimeout > 0) {
s.connect(new InetSocketAddress(server, port), defaultConnectTimeout);
} else {
s.connect(new InetSocketAddress(server, port));
}
}
As you see, the domain resolution is always handled by InetSocketAddress:
public InetSocketAddress(String hostname, int port) {
if (port < 0 || port > 0xFFFF) {
throw new IllegalArgumentException("port out of range:" + port);
}
if (hostname == null) {
throw new IllegalArgumentException("hostname can't be null");
}
try {
addr = InetAddress.getByName(hostname);
} catch(UnknownHostException e) {
this.hostname = hostname;
addr = null;
}
this.port = port;
}
As you can see, InetAddress.getByName is called everytime. I think that you method is safe.
I am trying to send an HTML POST request over telnet in Java, I have some XML content which I have to send. But when I try to achieve in java, i am getting "Connection Reset" error. But the same when I do it over putty(unix), I am getting the response xml correctly.
Java Program I used : (Resulting in Connection Reset error)
public class Telnet {public static void main(String[] args) throws Exception {
Socket socket = new Socket("hostname", 10020);
String xmled = "<?xml version=1.0?><methodCall><methodName>GetVoucherDetails</methodName><params><param><value><struct><member><name>serialNumber</name><value><string>1038291567</string></value></member><member><name>networkOperatorId</name><value><string>vno2</string></value></member></struct></value></param></params></methodCall>";
System.out.println("Params: " + xmled);
try {
Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
out.write("POST /someContext HTTP/1.1\r\n");
out.write("Accept: text/xml\r\n");
out.write("Connection: close\r\n");
out.write("Content-Length: 489\r\n");
out.write("Content-Type: text/xml\r\n");
out.write("Host: ws2258:10010\r\n");
out.write("User-Agent: ADM/2.4/6.2\r\n");
out.write("Authorization: Basic cHBtc3VzZXI6dnNfJF9wcG11NWVy\r\n");
out.write(xmled);
out.write("\r\n");
out.flush();
InputStream inputstream = socket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
String string = null;
string = bufferedreader.readLine();
System.out.println(string);
while ((string = bufferedreader.readLine()) != null) {
System.out.println("Received " + string);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
socket.close();
}
}
}
Please suggest me something, I am new to socket programming.
In your Socket constructor, did you mean to put port 10020? HTTP implies port 80 unless your web server is listening on port 10020.
I finally have found the solution for this problem. The fix was quiet simple at the end. We had to send the entire XML content in one single line rather then putting into multiple lines.
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?