Java PING a range of IP Address [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
Java program to ping single IP Address
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class PingIP {
public static void runSystemCommand(String command) {
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader inputStream = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String s = "";
// reading output stream of the command
while ((s = inputStream.readLine()) != null) {
System.out.println(s);
}
....
}
But can i ping a range of IP Address with java.

If you're just trying to execute a bash command which pings a range, you're better off to use nmap
A working example:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException, InterruptedException {
final List<String> command = new ArrayList<>();
command.add("nmap");
command.add("-T5");
command.add("-sP");
command.add("172.19.0.0-255");
executeCommand(command);
}
private static int executeCommand(final List<String> command) {
try {
final ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash").command(command);
processBuilder.redirectErrorStream(true);
System.out.println("executing: " + processBuilder.command().toString());
final Process process = processBuilder.start();
final InputStream inputStream = process.getInputStream();
final InputStream errorStream = process.getErrorStream();
readStream(inputStream);
readStream(errorStream);
return process.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return -1;
}
private static void readStream(final InputStream iStream) {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(iStream))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
This could be refactored down to be more specific, but for your basic user case this gives some flexibility.

Related

Problems running frequent bash commands in Java HTTP Server

I implemented a simple HTTP Server that once calling an endpoint, it will retrieve a text file from S3 and returns it. Unfortunately, when the requests are high, like 100 times per second, it goes to unstable state and can't respond to HTTP requests and they go to timeout. For accessing the S3, I'm run a bash command (which one command takes 2s to execute), so one thought I have is maybe the frequent bash commands and pipes is not efficient. And to add, we are running the code in kubernetes in case it might also cause resource restrictions, etc.
What is the problem? Is it the frequent pipes, HTTP Server API, etc? How to address it?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class FileRetriever implements Runnable {
HttpServer server;
ProcessBuilder processBuilder;
public FileRetriever() {
processBuilder = new ProcessBuilder();
Thread t = new Thread(this);
t.start();
}
public void run() {
try {
server = HttpServer.create(new InetSocketAddress(serverPort), 0);
server.createContext("/getfile", new GetFileHandler());
server.setExecutor(null);
server.start();
} catch (IOException e) {
logger.error("HttpServer ERROR", e);
}
}
class GetFileHandler implements HttpHandler {
#Override
public void handle(HttpExchange he) throws IOException {
// parse request
// http://localhost:9003/getfile?id=xxxxx
String response = "";
URI requestedUri = he.getRequestURI();
String query = requestedUri.getRawQuery();
String pair[] = query.split("=");
String id="";
if (pair[0].equals("id")) {
id = pair[1];
try {
String command = "aws --endpoint-url="+S3server+" s3 cp s3://file-store/"+id+"/files/"+id+".txt -";
processBuilder.command("sh", "-c", command+" ; true");
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader readerErrors = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
while ((line = reader.readLine()) != null) {
response+=line+"\n";
}
if(response.trim().equals("")) {
response="Not Found";
he.sendResponseHeaders(404, response.length());
}
else {
logger.info("Received file successfully: " + id);
he.sendResponseHeaders(200, response.length());
}
} catch (Exception e) {
response = "ERROR in GetFileHandler.";
}
OutputStream os = he.getResponseBody();
os.write(response.toString().getBytes());
os.close();
}
}
}
}

WMIC Java command not working after exe installation

A very simple code running in the debugging mode perfectly but not working after installation of exe, giving no response/result in return. even no errors to trace.
After building a .exe and installing on my PC its happening, very strange.
tried process builder but the same thing, anyway to check/trace it. maybe paths ?
StringBuilder b = new StringBuilder();
Process p = Runtime.getRuntime().exec("wmic diskdrive get signature");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
b.append(line);
}
Please note: CMD /c before commands also return an empty response in actual env.
An internal windows command with arguments, like "wmic diskdrive ..."
can be executed easily by wrapping it up inside a cmd window.
Here is the working code snippet for running the wmic command encapsulated in a cmd window:
import java.io.*;
public class Wmic {
public static void main(String[] args) {
StringBuilder b = new StringBuilder();
try {
// Initialize a process object to run
// wmic command and its parameters
// inside a cmd window
Process process = Runtime.getRuntime()
.exec("cmd /c C:\\Windows\\System32\\wbem\\WMIC.exe diskdrive get signature");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
b.append(line);
}
} catch (Exception ex) {
b.append(ex.toString());
}
System.out.println("Output: \n" + b.toString());
}
}
Output:
>javac Wmic.java
>java Wmic
Output:
Signature
More information:
https://mkyong.com/java/how-to-execute-shell-command-from-java/
The ProcessBuilder constructor takes a list of strings. When using ProcessBuilder to run a command, I separate all the words in the command into separate strings.
I read the output of the process in a separate thread. And I always wait for the command, that I launched via ProcessBuilder, to terminate.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
public class PrcBldTs {
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder("wmic","diskdrive","get","signature");
try {
Process proc = pb.start();
StreamGobbler error = new StreamGobbler(proc.getErrorStream());
StreamGobbler output = new StreamGobbler(proc.getInputStream());
Thread stdout = new Thread(output);
Thread stderr = new Thread(error);
stdout.start();
stderr.start();
int result = proc.waitFor();
stdout.join();
stderr.join();
System.out.println("Exit status = " + result);
if (result != 0) {
System.out.println(error.getContents());
}
else {
System.out.println(output.getContents());
}
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
class StreamGobbler implements Runnable {
private BufferedReader reader;
private StringWriter sw;
public StreamGobbler(InputStream is) {
InputStreamReader isr = new InputStreamReader(is);
reader = new BufferedReader(isr);
sw = new StringWriter();
}
public String getContents() {
return sw.toString();
}
public void run() {
try {
String line = reader.readLine();
while (line != null) {
sw.append(line);
sw.append(System.lineSeparator());
line = reader.readLine();
}
}
catch (IOException xIo) {
throw new RuntimeException(xIo);
}
}
}
Running the above code gave me the following output.
Exit status = 0
Signature
1145609371

Java Client/Server does not return UTF-8 string

I tried to pass a UTF-8 String through a Java Socket.
The String contains a mix of English and Greek.
My problem is that when the message passes through the socket all Greek characters turn to "?".
I already tried to set the InputStream character set to UTF-8.
Bellow is my attempt, any help will be appreciated.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
try {
String msg = "This is a test - Αυτο ειναι μια δοκιμη";
ServerSocket serverSocket = new ServerSocket(9999);
Thread host = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Socket socket = serverSocket.accept();
if (socket != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
while (true) {
String line = bufferedReader.readLine();
if (line != null) {
System.out.println(line);
} else if(bufferedReader.read() < 0) {
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
host.start();
Socket socket = new Socket("127.0.0.1", 9999);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Edit 1
I run and build my code through IntelliJ Idea and that is where I found the problem.
But after #Ihar Sadounikau comment I updated and my JDK and tried to build and run through PowerShell but still the problem persists.
And this is my result
& 'C:\Program Files\Java\jdk-13.0.2\bin\java.exe' Main
This is a test - ??τ? ε??α? ??α δ?????
With this line: PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true); you are converting a bytestream (i.e., InputStream / OutputStream into a charstream (i.e., Reader / Writer). Anytime you do that, if you fail to specify the encoding, you get platform default, which is unlikely what you want.
You (and #IharSadounikau) are seeing different results, because the 'platform default' is switching around on you. It's one of the reasons you REALLY do not want to use it, ever. Figuring out that your code has the bug where it only works if your platform default encoding is the same as the person who developed it – is generally untestable.
Try new PrintWriter(socket.getOutputStream(), true, StandardCharsets.UTF_8).
Maybe this will help:
String msgEncode = URLEncoder.encode(msg, "UTF-8");
printWriter.println(msgEncode);
And:
String line = bufferedReader.readLine();
String msgDecode = URLDecoder.decode(line, "UTF-8");

compiling java file from another java class

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ExecuteShellComand {
public static void main(String[] args) {
ExecuteShellComand obj = new ExecuteShellComand();
String className = "str.java";
String command = "javac " + className;
String output = obj.executeCommand(command);
System.out.println(output);// prints the output of the executed command
}
private String executeCommand(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
} catch (Exception e) {
e.printStackTrace();
}
return output.toString();
}
}
I am trying to compile a Java file (str.java) from another Java class(ExecuteShellComand.java). What I am trying to do is if "str.java" compiles successfully then I want to execute "java str" command, but if the compilation fails then proper stacktrace or errors should be printed. I am storing the stacktrace or the errors in output variable.
But when I execute this code although "str.java" has somes errors in it System.out.println(output) is not printing the errors.
If you want to capture the errors from a command then you shall capture error stream instead of Input stream
So replace
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
with
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
The Process class tries to mimetize OS process. It means, process keep different output stream for error and normal messages and one stream for input. In UNIX, should be:
wc < file > wc.count 2> wc.error
In Java...
abstract InputStream getErrorStream()
Gets the error stream of the subprocess.
abstract InputStream getInputStream()
Gets the input stream of the subprocess.
abstract OutputStream getOutputStream()
So, you should use getErrorStream() to get errors..
Refactoring your code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ExecuteShellComand {
public static void main(String[] args) {
ExecuteShellComand obj = new ExecuteShellComand();
String className = "str.java";
String command = "javac " + className;
obj.executeCommand(command);
System.out.println(obj.output);
System.out.println(obj.errors);
}
private String errors;
private String output;
private void executeCommand(String command) {
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
errors = readStream(p.getErrorStream());
output = readStream(p.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
private String readStream(InputStream inputStream) throws IOException {
StringBuffer output = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
return output.toString();
}
}

pipe telnet output to logfile with tee command using Java process exec

Concurrency and stream reading in a project for a simple MUD client is proving a bit of headache, so I'm trying to find an alternative. The tee command looks to fit the bill for concurrently splitting output between a file and the terminal. How do I then send messages through the telnet session?
Splitting remote output between the console and a file:
thufir#dur:~/NetBeansProjects/TelnetConsole$
thufir#dur:~/NetBeansProjects/TelnetConsole$ telnet rainmaker.wunderground.com 3000 | tee out.txt
Trying 38.102.137.140...
Connected to rainmaker.wunderground.com.
Escape character is '^]'.
------------------------------------------------------------------------------
* Welcome to THE WEATHER UNDERGROUND telnet service! *
How do I then pipe or somehow send Java messages to the system telnet client? Or, perhaps, would it make more sense to use exec and start the telnet session, and tee, from within Java? Just looking for a good approach.
Yes, exec sounds like a better solution since you want to control both input and outpud data. And do you really need tee in when you use exec, I don't understand why...
Also take a look at netcat instead of telnet - telnet has some special character handling that could give you trouble if you plan to send binary data.
By no means functioning code, but definitely simpler than using Apache TelnetClient. However, it's not possible to use the pipe command(?) with java exec:
package exec;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
class Ideone {
public static void main(String[] args) throws IOException {
new Ideone().start();
}
public void start() throws IOException {
String[] s = new String[6];
s[0] = "telnet";
s[1] = "rainmaker.wunderground.com";
s[2] = "3000";
s[3] = "|";
s[4] = "tee";
s[5] = "out.log";
for (int i=0;i<s.length;i++ ) {
System.out.println(s[i]);
}
Process process = Runtime.getRuntime().exec(s);
OutputStream stdin = process.getOutputStream();
InputStream stderr = process.getErrorStream();
InputStream stdout = process.getInputStream();
read();
write(stdout);
}
private void parseLog() {
//read the log file, automate responses
}
private void write(InputStream stdin) throws UnsupportedEncodingException, IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stdin, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
private void read() {
Thread read = new Thread() {
String command = null;
#Override
public void run() {
BufferedReader bufferedInput = new BufferedReader(new InputStreamReader(System.in));
do {
try {
command = bufferedInput.readLine();
} catch (IOException ex) {
System.out.println(ex);
} finally {
}
} while (true);
}
};
read.start();
}
}

Categories

Resources