I'm trying to get current network speed like shown in System Monitor on GNOME.
I need this to be in terminal and if possible no installations needed (on most of distros this tool i need should be installed by default with the system).
So i don't want to ping anything or stuff like that, I just want to check speed in simplest way possible without adding new tools.
I hope there is a tool that will show information in terminal like System Monitor -> Resources -> Network history.
EDIT:
if there is a workaround in Java to get this information without using linux commands this would be great
It's difficult to know what tools you already have installed on your system. I'd recommend either bmon, ifstat, or ifstat -S if you want the information printed on the same time.
The above should be in your distro's central repository (aptitude, yum etc) so should be easy to install if they're not aready there.
The Java class InetAddress has an isReachable() method. You could try this:
public long getSpeed() {
InetAddress inet = InetAddress.getByName("stackoverflow.com");
long start = System.currentTimeMillis();
boolean reachable = inet.isReachable(5000);
if (reachable) {
long end = System.currentTimeMillis();
return end - start;
} else {
return -1;
}
}
This will 'sort of' do a ping, but how the isReachable() method is implemented is not really specified. Doing an actual ping command from Java itself is not supported though, so this is (I think) the best you can do.
Related
I am extremely new the Android app development and Stack Overflow. I am trying to recreate traceroute in an Android app since Android devices do not come with traceroute by default. I've encountered a couple stack overflow posts talking about solutions to this, but I have still run into challenges.
Traceroute on android - the top post on this thread links an Android Studio project that implements traceroute using ping. If I understand the algorithm correctly, it continually pings the destination IP, incrementing the time-to-live field to obtain information about intermediary routers. I've tried to recreate this behavior, but for certain values of TTL, the ping stalls and doesn't retrieve any router information. I'm not really sure why this happens. Here's a quick demo function I spun up... at some point in the loop the pings stall.
public static void smallTracerouteDemoShowingThatTheProgramStallsAtCertainTTLs() {
try {
String host = "google.com";
int maxTTL = 20;
for (int i = 1; i < maxTTL; i++) {
// Create a process that executes the ping command
Process p = Runtime.getRuntime().exec("ping -c 1 -t " + i + " " + host);
// Get a buffered reader with the information returned by the ping
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
// Convert the BufferedReader to a string
String dataReturnedByPing = "";
for (String line; (line = br.readLine()) != null; dataReturnedByPing += "\n"+line);
// Print out information about each TTL
System.out.println("TTL = " + i + " out of " + maxTTL);
System.out.println(dataReturnedByPing);
System.out.println("========================================");
}
} catch (Exception e) {
e.printStackTrace();
}
}
how to run traceroute command through your application? - The solution on this thread suggests using BusyBox. I've not used BusyBox as yet, but it seems like I would have to embed BusyBox into my app to get things to work. After doing some research it looks like BusyBox provides numerous Linux commands through one executable. I'm a bit hesitant to explore this option because I really only need the traceroute command. In addition, I know that Android targets a few different CPU architectures, and I'm not sure if one executable will support them all.
I've also run into a github repository that takes another approach to running traceroute:
https://github.com/wangjing53406/traceroute-for-android - In this repository the author embeds the traceroute source code into the project and uses the NDK to build the source code along with the rest of his app. I really like this approach because it feels the most "correct." It uses a built traceroute instead of a Java-based implementation, so you can't find yourself in a situation where the Java implementation gives you one thing and the actual traceroute gives you another. When I open this project to experiment with it, my build fails. The top line says:
org.gradle.initialization.ReportedException: org.gradle.internal.exceptions.LocationAwareException: A problem occurred configuring root project 'traceroute-for-android-master'.
Any help on why this happens or ways to troubleshoot it would be fantastic.
For reference, the minimum SDK I am targeting is API 21 and I am running on Android Studio 3.3.0.
So, at this point I'm stumped. If you were trying to make an app that would let you execute traceroute commands, how would you do it? I really like the NDK approach because it guarantees you're getting true traceroute behavior. If you have any guides to getting that set up for my Android version/SDK, I would appreciate if you would post them. If you'd take another approach I'd to hear about it as well.
Thank you in advance.
I found this on choco-solver documentation but i do not know how use it with provided choco-solver sample program in order to profile.
NB: I already install cpprofiller in my machine and launch it. So it start a tcp server on port 6565.
Need help please.
First, make sure your code looks like:
try (CPProfiler profiler = new CPProfiler(s1.getSolver(), true)) {
solver.findSolution();
}
Then, you should start CPProfiler first and then run run Java program.
Once you go back to the CPProfiler interface, you should see the search tree being updated.
When does the 'Optional<Duration> totalCpuDuration();' method of ProcessHandle.Info return information?
I've tried with and without sudo, doesn't seem to make much difference; either way only the current process returns non-empty value. The documentation does not say much.
What stops the JVM stdlib running under sudo (on MacOS or Linux) from getting that information? Is it just not implemented? Would getting that info be too slow?
This has nothing to do with permissions, at least on MacOS: it's just not implemented (as of May 2021).
For linux, the code seems to read the cpu time via the proc fs for all processes, or at least try to, permissions might apply.
For MacOS, it only reads info for the current process. It's hardcoded: if (pid == getpid()) { ... }; no attempt is made to get this info from other processes.
MacOS:
https://github.com/openjdk/jdk15u/blob/master/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c
Linux:
https://github.com/openjdk/jdk15u/blob/master/src/java.base/linux/native/libjava/ProcessHandleImpl_linux.c
And here's an answer with some code to implement a workaround with Java and shell exec:
https://stackoverflow.com/a/36381244/336356
An alternative way of getting Total CPU Duration of your process is this
ProcessHandle processHandle = ProcessHandle.of(<system pid>).get();
ProcessHandle.Info processInfo = processHandle.info();
long timeDiff = Instant.now().getEpochSecond() - processInfo.startInstant().get().getEpochSecond();
This works for any process that user has access to, not just current process.
We know how to force shutdown an computer using Java. For example, the following code works fine for force shutdown:
public static void main(String arg[]) throws IOException{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("shutdown -s -t 0");
System.exit(0);
}
Now, suppose if I want to force startup a computer (which is in shut down state), at a particular time, is it possible to do in Java or any other language?
You need something to trigger the startup. The best way to trigger this is Wake On Lan.
If you want to do this in Java, this might be a good resource.
In addition to wake on lan, there are IPMI devices that run on some server-grade hardware that is connected to the motherboard and can control power as well as provide serial console output over a network connection. This computer is running all the time, but I'm not familiar with any you can load your own code onto.
You can control this device remotely to power control the server that is off from any language including java.
http://en.wikipedia.org/wiki/Intelligent_Platform_Management_Interface
If your BIOS supports Advanced Power Management (APM) version 1.2 or later, it should be possible to wake it from sleep/standy or hibernation based on a timer. On Windows an end user can do this through Task Scheduler, and if you wish to do it programmatically you can use the Task Scheduler interfaces.
I don't know how you would do this through Java, but here is some example C code that will create a task to wake the computer up 2 minutes in the future:
#include <mstask.h>
#include <time.h>
int main() {
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr)) {
ITaskScheduler *scheduler;
hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void**)&scheduler);
if (SUCCEEDED(hr)) {
ITask *task;
hr = scheduler->NewWorkItem(L"Wake Timer", CLSID_CTask, IID_ITask, (LPUNKNOWN*)&task);
if (SUCCEEDED(hr)) {
WORD index;
ITaskTrigger *trigger;
hr = task->CreateTrigger(&index, &trigger);
if (SUCCEEDED(hr)) {
time_t t = time(NULL) + 120;
struct tm *ltime = localtime(&t);
TASK_TRIGGER triggertime;
memset(&triggertime, 0, sizeof(triggertime));
triggertime.cbTriggerSize = sizeof(TASK_TRIGGER);
triggertime.wBeginYear = ltime->tm_year+1900;
triggertime.wBeginMonth = ltime->tm_mon+1;
triggertime.wBeginDay = ltime->tm_mday;
triggertime.wStartHour = ltime->tm_hour;
triggertime.wStartMinute = ltime->tm_min;
triggertime.TriggerType = TASK_TIME_TRIGGER_ONCE;
trigger->SetTrigger(&triggertime);
trigger->Release();
}
task->SetFlags(TASK_FLAG_DELETE_WHEN_DONE|TASK_FLAG_SYSTEM_REQUIRED|TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
task->SetAccountInformation(L"", NULL);
IPersistFile *file;
hr = task->QueryInterface(IID_IPersistFile, (void**)&file);
if (SUCCEEDED(hr)) {
file->Save(NULL, TRUE);
file->Release();
}
task->Release();
}
scheduler->Release();
}
CoUninitialize();
}
return 0;
}
Assumedly if you can do this on Windows, there must be equivalent APIs for other operating systems.
I did manage to find a similar question floating around on the internet, so I'll post the links here to see if you find it helpful. (this was the thread I found: http://www.coderanch.com/t/440680/gc/interact-Windows-Task-Scheduler-Java)
First of all though, I might add that Java is a language that must run in a Virtual Machine - there are no two ways around it. I'm not well versed in 'low-level' programming, such as programming at closer to BIOS level, which is sort of where we are heading with this.
As the question was explicitly about Java, the best I could come up with from research, is (if you're really wanting to use Java for something), using the JAVA-COM (JACOB) http://sourceforge.net/projects/jacob-project/ which allows you to hook into the Windows Task Scheduler http://msdn.microsoft.com/en-us/library/aa383581%28VS.85%29.aspx via the COM language (AF
As far as I am aware, because Java needs to be in a virtual machine to run, there would be no way of getting it to do an action such as turning on a PC - let's not even get into issues of whether such an action would require administrator or above privileges.
Hope that helps.
I want to be able to do something like that:
Process p = getRunningProcess(pid)
If there's a way, does it matter how the process was created (using java, using python, from the shell, etc...)?
It is possible to attach to another JVM process from Java app (e.g. to be able to monitor what's going on and potentially detect problems before they happen). You can do this by using the Attach API. Don't know much about attaching to non-JVM processes.
String name = ...
List vms = VirtualMachine.list();
for (VirtualMachineDescriptor vmd: vms) {
if (vmd.displayName().equals(name)) {
VirtualMachine vm = VirtualMachine.attach(vmd.id());
String agent = ...
vm.loadAgent(agent);
// ...
}
}
Yes there is a way to attach any non-JVM process with ProcessHandle.
Here a code Example that starts the calculator and closes it by using the pid.
Process calc = Runtime.getRuntime().exec("gnome-calculator");
Thread.sleep(2000);
long pid = calc.pid();
Optional<ProcessHandle> optionalProcessHandle = ProcessHandle.of(pid);
optionalProcessHandle.ifPresent(ProcessHandle::destroy);
But make sure to run Java SE/JDK 11 or higher and to import java.util.Optional;.
See the documentation to see further methods that can be used with ProcessHandle:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ProcessHandle.html
Credits to java.lang.ProcessHandle - compilation error for being a template for this.