Android internet speed test - java

I am developing a speed test app like OKLA app (http://www.speedtest.net/).
I've been trying to get bandwidth rate with the most common approach:
Get the time before downloading.
Download some file for some time X.
Get the time after downloading and the total size downloaded.
Calculate speed from TIME and BYTES RECEIVED.
Also, I execute this in two different threads at the same time because is required to saturate de connection to achieve good results.
This approach works very well on PC environment with this JAVA code:
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class TestVelocidad {
static long totalBytesReceived = 0; //
static long startSample;
static long endSample ;
private static final long TIME_FOR_DOWNLOAD_MILISECONDS = (long) 10000.0;
private static final long MILI_TO_NANO = 1000000;
public static void main(String[] args) throws InterruptedException, ExecutionException {
try{
final ExecutorService service;
String downloadFileUrl100MB = "http://cachefly.cachefly.net/100mb.test";
startSample = System.nanoTime();
service = Executors.newFixedThreadPool(6);
FutureTask futureTask_1 = new FutureTask(new SpeedTestThread(downloadFileUrl100MB));
service.execute(futureTask_1);
FutureTask futureTask_2 = new FutureTask(new SpeedTestThread(downloadFileUrl100MB));
service.execute(futureTask_2);
service.shutdownNow();
long result1 = (Long) futureTask_1.get();
long result2 = (Long) futureTask_2.get();
endSample = System.nanoTime();
long timeSpent = (long) endSample-startSample;
long totalBytesReceived = result1 + result2;
System.out.println("Time of threads: " + timeSpent/1000000000.0 + " seconds " + "\nbytes received: " + (totalBytesReceived) );
double calculatedSpeed;
// long finalTimeSpent ;
// finalTimeSpent = (long) ((TIME_FOR_DOWNLOAD_MILISECONDS * MILI_TO_NANO - diff));
calculatedSpeed = SpeedInfo.calculate(timeSpent, totalBytesReceived).megabits;
System.out.println("Velocidad calculada: " + calculatedSpeed + " mbps" );
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class SpeedTestThread implements Callable<Long> {
private String url = new String("");
private static final long TIME_FOR_DOWNLOAD_NANOSECONDS = (long) 10000000000.0;
private static final long MILI_TO_NANO = 1000000;
private long bytesThread;
public SpeedTestThread(String urlToDownload){
url = urlToDownload;
}
public void run() {
}
#Override
public Long call() throws Exception {
System.out.println("FileDownload " + " File to download: " + url );
InputStream stream = null;
long startCon = System.nanoTime();
URL urlToDownload = null;
try {
urlToDownload = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection con = null;
try {
con = urlToDownload.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
con.setUseCaches(false);
//Tiempo de acceso al archivo.
long connectionLatency = (System.nanoTime() - startCon)/MILI_TO_NANO;
System.out.println("Connection latency = " + connectionLatency + "");
con.setConnectTimeout(5000);
try {
stream = con.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
long startNano = System.nanoTime();
int currentByte = 0;
try {
while ((currentByte = stream.read()) != -1 ) {
bytesThread++;
if ((System.nanoTime() - startNano) > TIME_FOR_DOWNLOAD_NANOSECONDS){
System.out.println("Time");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Thread bytes received: " + bytesThread);
return bytesThread;
}
}
class SpeedInfo {
public double kilobits = 0;
public double megabits = 0;
public double downspeed = 0;
private static final double BYTE_TO_KILOBIT = 0.008;
private static final double KILOBIT_TO_MEGABIT = 0.001;
/**
* 1 byte = 0.0078125 kilobits
* 1 kilobits = 0.0009765625 megabit
*
* #param downloadTime in miliseconds
* #param bytesIn number of bytes downloaded
* #return SpeedInfo containing current testVelocidadThread
*/
public static SpeedInfo calculate(final long downloadTime, final long bytesIn) {
SpeedInfo info = new SpeedInfo();
//from mil to sec
System.out.println("Bytes transferidos: " + bytesIn + "Tiempo de descarga: " + downloadTime/1000000000);
double time = downloadTime;
double byteIn1 = bytesIn;
double division = (double)(byteIn1 / time);
double bytespersecond = ((division) * 1000000000);
double kilobits = bytespersecond * BYTE_TO_KILOBIT;
double megabits = kilobits * KILOBIT_TO_MEGABIT;
info.downspeed = bytespersecond;
info.kilobits = kilobits;
info.megabits = megabits;
return info;
}
}
The problem is when I run this on a Android application, I had good results on phones with more processing and memory capacity, but poor results on phones with lower capacity.
Any good ideas to achieve good results on most android's phones?.

try to download the file with java nio rather than java io
java io transfer the file first to memory which make the performance poor on low end devices
while java nio using channels you can transfer the file to storage which will make the performance same on all devices approximately
use this code :
len = out.getChannel().transferFrom(readableByteChannel , seekPos , Long.MAX_VALUE);

Related

Java midi program selection strange behaviour

I've tried to find any information regarding this but I haven't been able to find anything that helps.
I'm trying to make a program that generates a midi-file consisting of two instruments playing at once using different instruments(programs) on them. I have been using a sample program:
http://www.cs.cornell.edu/courses/cs211/2008sp/examples/MidiSynth.java.txt
as a template but when I try and create the midi events artificially(as opposed to generating them on the fly with the synth in the sample program), the resulting midi-file doesn't seem to care that I have switched programs, using the last changed-to program for every note in the file, consisting of two midi-tracks, even though I have saved program-change data to both tracks. I have pasted the code for my program beneith:
import java.io.File;
import java.io.IOException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Soundbank;
import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Instrument;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
import javax.sound.midi.InvalidMidiDataException;
public class MidiTest2
{
/* This velocity is used for all notes.
*/
private static final int VELOCITY = 64;
final int PROGRAM = 192;
final int NOTEON = 144;
final int NOTEOFF = 128;
long startTime;
Sequence sequence;
Synthesizer synthesizer;
Sequencer sequencer;
Instrument instruments[];
ChannelData channels[];
ChannelData cc;
//int instrumentCounter = 0;
Track track;
MidiTest2(){
try{
if(synthesizer == null){
if((synthesizer = MidiSystem.getSynthesizer()) == null){
System.out.println("getSynthesizer() failed");
return;
}
}
synthesizer.open();
sequencer = MidiSystem.getSequencer();
sequence = new Sequence(Sequence.PPQ, 10);
}catch(Exception e){
e.printStackTrace();
return;
}
Soundbank sb = synthesizer.getDefaultSoundbank();
if(sb != null){
instruments = synthesizer.getDefaultSoundbank().getInstruments();
synthesizer.loadInstrument(instruments[0]);
}
MidiChannel midiChannels[] = synthesizer.getChannels();
channels = new ChannelData[midiChannels.length];
for(int i = 0; i < channels.length;++i){
channels[i] = new ChannelData(midiChannels[i], i);
}
cc = channels[0];
}
public void createShortEvent(int type, int num){
ShortMessage message = new ShortMessage();
try{
long millis = System.currentTimeMillis() - startTime;
long tick = millis * sequence.getResolution() / 500;
message.setMessage(type+cc.num, num, cc.velocity);
System.out.println("Type: " + message.getCommand() + ", Data1: " + message.getData1() + ", Data2: " + message.getData2() + ", Tick: " + tick);
MidiEvent event = new MidiEvent(message, tick);
track.add(event);
}catch (Exception e){
e.printStackTrace();
}
}
public void createShortEvent(int type, int num, int eventTime){
ShortMessage message = new ShortMessage();
try{
//long millis = System.currentTimeMillis() - startTime;
long tick = eventTime * sequence.getResolution();
message.setMessage(type+cc.num, num, cc.velocity);
System.out.println("Type: " + message.getCommand() + ", Data1: " + message.getData1() + ", Data2: " + message.getData2() + ", Tick: " + tick);
MidiEvent event = new MidiEvent(message, tick);
track.add(event);
}catch (Exception e){
e.printStackTrace();
}
}
public void saveMidiFile(){
try {
int[] fileTypes = MidiSystem.getMidiFileTypes(sequence);
if (fileTypes.length == 0) {
System.out.println("Can't save sequence");
} else {
if (MidiSystem.write(sequence, fileTypes[0], new File("testmidi.mid")) == -1) {
throw new IOException("Problems writing to file");
}
}
} catch (SecurityException ex) {
} catch (Exception ex) {
ex.printStackTrace();
}
}
void run(){
//System.out.println("sequence: " + sequence.getTracks().length);
createNewTrack(0);
createShortEvent(NOTEON, 60, 2);
createShortEvent(NOTEOFF, 60, 3);
createShortEvent(NOTEON, 61, 3);
createShortEvent(NOTEOFF, 61, 4);
createShortEvent(NOTEON, 62, 4);
createShortEvent(NOTEOFF, 62, 5);
createShortEvent(NOTEON, 63, 5);
createShortEvent(NOTEOFF, 63, 6);
createNewTrack(5);
createShortEvent(NOTEON, 50, 1);
createShortEvent(NOTEOFF, 50, 5);
playMidiFile();
saveMidiFile();
}
void printTrack(int num){
Track tempTrack = sequence.getTracks()[num];
System.out.println(tempTrack.get(0).getTick());
}
void playMidiFile(){
try{
sequencer.open();
sequencer.setSequence(sequence);
}catch (Exception e){
e.printStackTrace();
}
sequencer.start();
}
void createNewTrack(int program){
track = sequence.createTrack();
programChange(program);
}
void programChange(int program){
cc.channel.programChange(program);
System.out.println("program: " + program);
startTime = System.currentTimeMillis();
createShortEvent(PROGRAM, program);
}
public static void main(String[] args)
{
MidiTest2 mt = new MidiTest2();
mt.run();
}
}
The ChannelData-class(that doesn't do anything but I thought I'd post it for completeness sake):
public class ChannelData {
MidiChannel channel;
boolean solo, mono, mute, sustain;
int velocity, pressure, bend, reverb;
int row, col, num;
public ChannelData(MidiChannel channel, int num) {
this.channel = channel;
this.num = num;
velocity = pressure = bend = reverb = 64;
}
public void setComponentStates() {
}
}
In the program I try to create 5 notes with the acoustic piano-sound and one note with an electric piano sound. However all notes are played back with the electric piano sound even though I create a new track before I switch instrument.
I have been trying to figure this out now for 5 hours or something and I'm all out of ideas.
Tracks can help your own program with organizing events, but they do not affect the synthesizer in any way.
To be able have different settings, you must use different channels.

Get CPU load per core using Java

I'm using this code to get CPU load from /proc/stat using Java code:
private static long PREV_IDLE; //CPU Idle time
private static long PREV_TOTAL; //CPU Total time
public static float getCPUProcOrig() throws Exception
{
BufferedReader cpuReader = null;
try
{
cpuReader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")));
String cpuLine = cpuReader.readLine();
if (cpuLine == null)
{
throw new Exception("/proc/stat didn't work well");
}
else
{
String[] CPU = cpuLine.split("\\s+");
long IDLE = Long.parseLong(CPU[4]);//Get the idle CPU time.
long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
// System.out.println("CPU: " + DIFF_USAGE + "%");
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
return (float) DIFF_USAGE;
}
}
catch (Exception e)
{
throw e; // It's not desirable to handle the exception here
}
finally
{
if (cpuReader != null)
try
{
cpuReader.close();
}
catch (IOException e)
{
// Do nothing
}
}
}
Unfortunately this code works well but for average CPU load. I would like to list all cores load separately. I tried to extend the code:
private static long PREV_IDLE; //CPU Idle time
private static long PREV_TOTAL; //CPU Total time
private static final int CONSERVATIVE = 0;
private static final int AVERAGE = 1;
private static final int OPTIMISTIC = 2;
public HashMap<String, HashMap<String, Float>> getCPUProc() throws Exception
{
BufferedReader cpuReader = null;
HashMap<String, HashMap<String, Float>> usageData = new HashMap<>();
try
{
String line;
cpuReader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")));
while ((line = cpuReader.readLine()) != null)
{
String[] CPU = line.split("\\s+");
if (CPU[0].startsWith("cpu"))
{
String cpuName = String.valueOf(CPU[0]);//Get the cpu number.
long IDLE = Long.parseLong(CPU[4]);//Get the idle CPU time.
long TOTAL = Long.parseLong(CPU[1]) + Long.parseLong(CPU[2]) + Long.parseLong(CPU[3]) + Long.parseLong(CPU[4]);
// System.out.println("IDLE : " + IDLE);
long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
// System.out.println("CPU: " + DIFF_USAGE + "%");
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
HashMap<String, Float> usageData2 = new HashMap<>();
usageData2.put("cpu", (float) DIFF_USAGE);
usageData.put(cpuName, usageData2);
}
// return (float) DIFF_USAGE;
}
}
catch (IOException | NumberFormatException e)
{
throw e; // It's not desirable to handle the exception here
}
finally
{
if (cpuReader != null)
try
{
cpuReader.close();
}
catch (IOException e)
{
// Do nothing
}
}
return usageData;
}
As you can see from the first code there are several static variables which are used to calculate the CPU load.
When I try to read all lines from /proc/stat these static variables are not used properly and data between the cores is messed up and the result is not accurate.
Can you help me to read the load properly? I'm out of ideas. How I can fix the code?
the problem is that lines:
long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
as you can see PREV_IDLE and PREV_TOTAL are shared between all cores; probably you want to keep them core-specific, so you should load that values before using them.
a nice idea would be instead of
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;
save them into usageData2

Java MODBUS RTU master example code

I need to write Modbus RTU master app in Java that support 03 - Read Holding Registers and 16 - Write Multiple Registers.
I found three java libraries: jamod, j2mod, modbus4j. I try all of these libraries (I spend about 4 hours) and it still doesn't work.
Do you know any step-by-step tutorial or example code?
I'm using USB->RS-485 converter. If I testing in QModBus, it works good.
Thank you.
import java.io.File;
import com.serotonin.io.serial.SerialParameters;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.code.RegisterRange;
import com.serotonin.modbus4j.exception.ModbusInitException;
public class Modbus4JTest {
public static void main(String[] args) throws Exception {
ModbusFactory factory = new ModbusFactory();
SerialParameters params = new SerialParameters();
params.setCommPortId("/dev/ttyUSB1");
params.setBaudRate(9600);
params.setDataBits(8);
params.setStopBits(1);
params.setParity(0);
ModbusMaster master = factory.createRtuMaster(params);
master.setTimeout(2000);
master.setRetries(0);
long start = System.currentTimeMillis();
// Don't start if the RTU master can't be initialized.
try {
master.init();
} catch (ModbusInitException e) {
System.out.println( "Modbus Master Init Error: " + e.getMessage());
return;
}
try {
System.out.println("Reg. 1001 Value:" + master.getValue(7, RegisterRange.HOLDING_REGISTER, 1000, DataType.FOUR_BYTE_FLOAT_SWAPPED));
// more like the above until all required register values are read.
// ..
}
finally {
master.destroy();
}
System.out.println("Time elapsed: " + (System.currentTimeMillis() - start) + "ms");
}
}
.
import java.io.File;
import com.ghgande.j2mod.modbus.ModbusCoupler;
import com.ghgande.j2mod.modbus.io.ModbusSerialTransaction;
import com.ghgande.j2mod.modbus.msg.ModbusRequest;
import com.ghgande.j2mod.modbus.msg.ReadInputRegistersRequest;
import com.ghgande.j2mod.modbus.msg.ReadInputRegistersResponse;
import com.ghgande.j2mod.modbus.net.SerialConnection;
import com.ghgande.j2mod.modbus.util.SerialParameters;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
// -Djava.library.path="/usr/lib/jni/"
public class J2mod {
public static void main(String[] args) throws Exception {
File lock = new File("/var/lock/LCK..ttyUSB0");
lock.delete();
File lock1 = new File("/var/lock/LCK..ttyUSB1");
lock1.delete();
SerialConnection con = null; // the connection
ModbusSerialTransaction trans = null; // the transaction
//ReadInputRegistersRequest req = null; // the request
ReadHoldingRegistersRequest req = null;
ReadHoldingRegistersResponse res = null;
//ReadInputRegistersResponse res = null; // the response
String portname = null; // the name of the serial port to be used
int unitid = 0; // the unit identifier we will be talking to
int ref = 0; // the reference, where to start reading from
int count = 0; // the count of IR's to read
int repeat = 1; // a loop for repeating the transaction
try {
portname = "/dev/ttyUSB1";
//System.setProperty("gnu.io.rxtx.SerialPorts", portname);
unitid = 2;
ref = 0;
count = 4;
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
// 2. Set master identifier
// ModbusCoupler.createModbusCoupler(null);
ModbusCoupler.getReference().setUnitID(1);
// 3. Setup serial parameters
SerialParameters params = new SerialParameters();
params.setPortName(portname);
params.setBaudRate(9600);
params.setDatabits(8);
params.setParity("None");
params.setStopbits(1);
params.setEncoding("rtu");
params.setEcho(false);
// 4. Open the connection
con = new SerialConnection(params);
con.open();
// 5. Prepare a request
req = new ReadHoldingRegistersRequest(unitid, ref, count);
//req = new ReadInputRegistersRequest(ref, count);
//req.setUnitID(unitid);
//req.setHeadless();
// 6. Prepare a transaction
trans = new ModbusSerialTransaction(con);
trans.setRequest(req);
int k = 0;
do {
trans.execute();
res = (ReadInputRegistersResponse) trans.getResponse();
//res = (ReadHoldingRegistersResponse) trans.getResponse();
for (int n = 0; n < res.getWordCount(); n++) {
System.out.println("Word " + n + "=" + res.getRegisterValue(n));
}
k++;
} while (k < repeat);
// 8. Close the connection
con.close();
}
}

Get memory and CPU usage

I would like to get the total physical memory, the CPU usage, and and the amount of memory being used. I have looked into Runtime.freeMemory(), but that isn't the free memory for the whole system.
I know I'm late with my answer, but I think this code is interesting.
This is an adaptation of "closed" code, and should be revised before aplying directly:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.Process;
import java.lang.Runtime;
import java.util.HashMap;
/**
* SystemStatusReader is a collection of methods to read system status (cpu and memory)
*
* #author Andreu Correa Casablanca
*/
public class SystemStatusReader
{
public static final int CONSERVATIVE = 0;
public static final int AVERAGE = 1;
public static final int OPTIMISTIC = 2;
/**
* cpuUsage gives us the percentage of cpu usage
*
* mpstat -P ALL out stream example:
*
* Linux 3.2.0-30-generic (castarco-laptop) 10/09/12 _x86_64_ (2 CPU) - To discard
* - To discard
* 00:16:30 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle - To discard
* 00:16:30 all 17,62 0,03 3,55 0,84 0,00 0,03 0,00 0,00 77,93
* 00:16:30 0 17,36 0,05 3,61 0,83 0,00 0,05 0,00 0,00 78,12
* 00:16:30 1 17,88 0,02 3,49 0,86 0,00 0,01 0,00 0,00 77,74
*
* #param measureMode Indicates if we want optimistic, convervative or average measurements.
*/
public static Double cpuUsage (int measureMode) throws Exception {
BufferedReader mpstatReader = null;
String mpstatLine;
String[] mpstatChunkedLine;
Double selected_idle;
try {
Runtime runtime = Runtime.getRuntime();
Process mpstatProcess = runtime.exec("mpstat -P ALL");
mpstatReader = new BufferedReader(new InputStreamReader(mpstatProcess.getInputStream()));
// We discard the three first lines
mpstatReader.readLine();
mpstatReader.readLine();
mpstatReader.readLine();
mpstatLine = mpstatReader.readLine();
if (mpstatLine == null) {
throw new Exception("mpstat didn't work well");
} else if (measureMode == SystemStatusReader.AVERAGE) {
mpstatChunkedLine = mpstatLine.replaceAll(",", ".").split("\\s+");
selected_idle = Double.parseDouble(mpstatChunkedLine[10]);
} else {
selected_idle = (measureMode == SystemStatusReader.CONSERVATIVE)?200.:0.;
Double candidate_idle;
int i = 0;
while((mpstatLine = mpstatReader.readLine()) != null) {
mpstatChunkedLine = mpstatLine.replaceAll(",", ".").split("\\s+");
candidate_idle = Double.parseDouble(mpstatChunkedLine[10]);
if (measureMode == SystemStatusReader.CONSERVATIVE) {
selected_idle = (selected_idle < candidate_idle)?selected_idle:candidate_idle;
} else if (measureMode == SystemStatusReader.OPTIMISTIC) {
selected_idle = (selected_idle > candidate_idle)?selected_idle:candidate_idle;
}
++i;
}
if (i == 0) {
throw new Exception("mpstat didn't work well");
}
}
} catch (Exception e) {
throw e; // It's not desirable to handle the exception here
} finally {
if (mpstatReader != null) try {
mpstatReader.close();
} catch (IOException e) {
// Do nothing
}
}
return 100-selected_idle;
}
/**
* memoryUsage gives us data about memory usage (RAM and SWAP)
*/
public static HashMap<String, Integer> memoryUsage () throws Exception {
BufferedReader freeReader = null;
String freeLine;
String[] freeChunkedLine;
HashMap<String, Integer> usageData = new HashMap<String, Integer>();
try {
Runtime runtime = Runtime.getRuntime();
Process freeProcess = runtime.exec("free -k"); // We measure memory in kilobytes to obtain a greater granularity
freeReader = new BufferedReader(new InputStreamReader(freeProcess.getInputStream()));
// We discard the first line
freeReader.readLine();
freeLine = freeReader.readLine();
if (freeLine == null) {
throw new Exception("free didn't work well");
}
freeChunkedLine = freeLine.split("\\s+");
usageData.put("total", Integer.parseInt(freeChunkedLine[1]));
freeLine = freeReader.readLine();
if (freeLine == null) {
throw new Exception("free didn't work well");
}
freeChunkedLine = freeLine.split("\\s+");
usageData.put("used", Integer.parseInt(freeChunkedLine[2]));
freeLine = freeReader.readLine();
if (freeLine == null) {
throw new Exception("free didn't work well");
}
freeChunkedLine = freeLine.split("\\s+");
usageData.put("swap_total", Integer.parseInt(freeChunkedLine[1]));
usageData.put("swap_used", Integer.parseInt(freeChunkedLine[2]));
} catch (Exception e) {
throw e;
} finally {
if (freeReader != null) try {
freeReader.close();
} catch (IOException e) {
// Do nothing
}
}
return usageData;
}
}
You can use SIGAR (http://support.hyperic.com/display/SIGAR/Home). I believe this is cross platform (I've only tried it on Windows) and I know it works (because I've tried it).
Javadoc: http://www.hyperic.com/support/docs/sigar/
Binaries: http://support.hyperic.com/display/SIGAR/Home#Home-binaries
Memory and CPU.
CPU example:
static final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
...
long start = threadBean.getCurrentThreadCpuTime();
for (int i = 0; i < 10000000; i++) {
...
}
long finish = threadBean.getCurrentThreadCpuTime();
On Linux you could open /proc/meminfo as a text file and parse the result.
Use JMX via 'jconsole', if this if for interactive use. It displays nice realtime graphs, and lots of other diagnostic information.

Threading using isReachable() on XP for subnet ping

I have written an app that should ping (use isReachable) for all the clients on the subnet the host sits on but I'm getting strange results when it is run on an XP machine (SP2) it fails to get all the hosts. It appears to be linked to threading as if I put in a join and effectively force the app to use one thread it works. It works fine in windows 7 and in ubuntu linux without the join so I'm a bit stumped as to why it falls over on XP. It's made up of two classes ill post them now. Also fairly new to java so hopefully it's nothing obvious. Thanks in advance.
Main.java
package subnetping;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
public static void main(String[] args) {
//Set this to your ip and netmask
Network myNetwork = new Network("192.168.1.33", 24);
Thread t = null;
for(String aHost : myNetwork.getClients()){
t = new Thread(new pinger(aHost));
t.start();
// Following makes it work on XP by forcing wait on thread
// try {
// t.join();
// } catch (InterruptedException ex) {
// Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
// }
}
}
public static class pinger implements Runnable{
private String host;
private InetAddress address;
public pinger(String host){
this.host = host;
try {
address = InetAddress.getByName(host);
} catch (UnknownHostException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void run(){
try {
if (address.isReachable(3000)) {
System.out.println(host + " reachable");
}
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Network.java
package subnetping;
import java.util.ArrayList;
import java.util.List;
public class Network {
private String subnet = "";
private int subnetMask;
private List<String> myClients = new ArrayList<String>();
public Network(String hostIP, int subnetMask){
this.subnetMask = subnetMask;
this.subnet = getSubNet(hostIP, this.subnetMask);
createClients();
}
private String ipToBinary(String ipNumber){
String[] temp;
String binOctet1;
String binOctet2;
String binOctet3;
String binOctet4;
String ipAsBinary;
temp = ipNumber.split("\\.");
binOctet1 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[0])));
binOctet2 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[1])));
binOctet3 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[2])));
binOctet4 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[3])));
ipAsBinary = binOctet1 + binOctet2 + binOctet3 + binOctet4;
return ipAsBinary;
}
private String binaryToIP(String binaryIP){
return longToIP(Long.parseLong(binaryIP, 2));
}
private Long ipToLong (String ipNumber){
String[] temp;
String binOctet1;
String binOctet2;
String binOctet3;
String binOctet4;
Long ipAsLong;
temp = ipNumber.split("\\.");
binOctet1 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[0])));
binOctet2 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[1])));
binOctet3 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[2])));
binOctet4 = padLeftToEight(Integer.toBinaryString(Integer.parseInt(temp[3])));
ipAsLong = Long.parseLong((binOctet1 + binOctet2 + binOctet3 + binOctet4),2);
return ipAsLong;
}
private String longToIP (Long LongIP){
String binOctet1;
String binOctet2;
String binOctet3;
String binOctet4;
int intOctet1;
int intOctet2;
int intOctet3;
int intOctet4;
String fullBin;
String ipAsString;
fullBin = padLeftToThirtyTwo(Long.toBinaryString(LongIP));
binOctet1 = fullBin.substring(0, 8);
binOctet2 = fullBin.substring(8, 16);
binOctet3 = fullBin.substring(16, 24);
binOctet4 = fullBin.substring(24);
intOctet1 = Integer.parseInt(binOctet1, 2);
intOctet2 = Integer.parseInt(binOctet2, 2);
intOctet3 = Integer.parseInt(binOctet3, 2);
intOctet4 = Integer.parseInt(binOctet4, 2);
ipAsString = intOctet1 + "." + intOctet2 + "." + intOctet3 + "." + intOctet4;
return ipAsString;
}
private String padLeftToEight(String octet){
String paddedOctet = octet;
if(octet.length() == 8){
return octet;
}else{
for( int i = 1; i <= (8 - octet.length()); i++){
paddedOctet = "0" + paddedOctet;
}
return paddedOctet;
}
}
private String padLeftToThirtyTwo(String ipNumber){
String paddedIPNumber = ipNumber;
if(ipNumber.length() == 32){
return ipNumber;
}else{
for( int i = 1; i <= (32 - ipNumber.length()); i++){
paddedIPNumber = "0" + paddedIPNumber;
}
return paddedIPNumber;
}
}
private String padRightToThirtyTwo(String ipNumber){
String paddedIPNumber = ipNumber;
if(ipNumber.length() == 32){
return ipNumber;
}else{
for( int i = 1; i <= (32 - ipNumber.length()); i++){
paddedIPNumber = paddedIPNumber + "0";
}
return paddedIPNumber;
}
}
private String getSubNet(String ipNumber, int subnetMask){
for(int i = 0; i < subnetMask; i++){
subnet = subnet + ipToBinary(ipNumber).charAt(i);
}
return binaryToIP(padRightToThirtyTwo(subnet));
}
private void createClients(){
long subnetLong;
long clientRange;
clientRange = ((long) Math.pow(2L, (32L - subnetMask)) - 2);
subnetLong = ipToLong(this.subnet);
for(int i = 1; i <= clientRange; i ++){
myClients.add(longToIP(subnetLong + i));
}
}
public List<String> getClients(){
return myClients;
}
}
Have shelled out to ping to cure the problem it not only didn't work properly on XP the isReachable() failed on a few hosts that ping found. Wasn't an ideal solution as now it's platform dependant but will be running WMI queries so tied to windows anyway.
Thanks for looking.

Categories