Ping error return always equals 0 - jscript

Having trouble getting this code to work. I can run the script (with changes) in vbscript and it runs fine. But I cant get this version to return a ping error return value other than 0. Any help is appreciated.
This is scanning a list of remote machines with checkboxes and returning the checked values. I want to run the ping to verify the remote machine are there before continuing. But with a error return of 0 for all queries its useless.
function statuschk3(){
var checkedValue = null;
var inputElements = document.getElementsByName("comp");
for(var i=0; inputElements[i]; ++i){
if(inputElements[i].checked)
{checkedValue = inputElements[i].value;
var WshShell = new ActiveXObject("WScript.Shell");
var status = WshShell.run ("ping -n 1 -a" + checkedValue + ",0 ,true");
if(status == 0)
{ var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.OpenTextFile("C:/script/testfile1.txt", 8, true);
s.WriteLine(checkedValue + " is turned off or off the domain");
s.Close();
}
else`

Here's a function I use to test connectivity. I use a vbscript version of this, but I rewrote it in javascript.
function Reachable(strComputer)
{
var wmiQuery = "Select * From Win32_PingStatus Where Address = '" + strComputer + "'";
var objWMIService = GetObject("winmgmts://./root/cimv2");
var colItems = objWMIService.ExecQuery(wmiQuery);
var enumItems = new Enumerator(colItems)
for (; !enumItems.atEnd(); enumItems.moveNext())
{
var objStatus = enumItems.item();
if ((objStatus.StatusCode == null) || (objStatus.Statuscode != 0))
{
return false //if computer is unreachable, return false
}
else
{
return true //'if computer is reachable, return true
}
}
}
Usage:
vbscript:
If Reachable(strComputer) Then MsgBox "Online" Else MsgBox "Offline"
javascript:
if (Reachable(strComputer)) { alert("Online") } else { alert("Offline") }
edit:
If you'd like to adjust the timeout of this, you can add the following to this line:
var wmiQuery = "Select * From Win32_PingStatus Where Address = '" + strComputer + "' and Timeout=500";
Where 500 is 500 milliseconds.
Here's more on the Win32_PingStatus class, where it says the default Timeout is 1000 milliseconds.
another edit to address your original question:
It looks like you have some syntax issues with your original code:
var status = WshShell.run ("ping -n 1 -a" + checkedValue + ",0 ,true");
needs to be
var status = WshShell.run ("ping -n 1 -a " + checkedValue, 0,true);
Notice the location of the space after a and the quotation marks after checkedValue
Also, the logic is backwards. if(status==0) then the device is ONLINE.

For what it's worth, if langstrom's WMI solution works, I think I prefer it over my own. My purpose in answering is to help you figure out what went wrong with your script.
Firstly, ping.exe can receive error responses from the gateway saying "no route to host" or similar. But having received responses (erroneous or not), the exit status is 0. It's better to check the output of the command for valid responses to determine success / fail.
But the more immediate problem is that shellObj.run() is forking the ping process asynchronously. It's non-blocking.
Using shellObj.exec() solves both problems. Here's an example using console JScript:
// returns 0 for success, non-zero for fail
function ping(host) {
var osh = WSH.CreateObject('Wscript.Shell'),
proc = osh.exec('ping -n 1 ' + host);
while (!proc.Status) WSH.Sleep(25);
return !/\btime\b/i.test(proc.StdOut.ReadAll());
}
Unfortunately, since browser / HTA JScript doesn't understand WSH or Sleep, you have to get creative with setInterval to block until the ping executable is finished. (This is why langstrom's WMI solution would be preferable to spawning an executable. Trying to hack a non-blocking command into something that blocks is cumbersome and awkward with HTA JScript.)
// alerts true on success, false on fail
function ping(host) {
var osh = new ActiveXObject('Wscript.Shell'),
proc = osh.exec('ping -n 1 ' + host),
waitForExit = setInterval(function() {
if (proc.Status) {
clearInterval(waitForExit);
alert(/\btime\b/i.test(proc.StdOut.ReadAll()));
}
}, 25);
}
ping('localhost');

Related

how to find (WLAN)-devices with a Node-App?

I am working on my first Node-App, which I want to connect to two Raspberrys and then control them. Like turn on and off an motion detector or start a webcam.
I have looked around and saw that people mentioned to make the Raspberry to an web server and then connect it.
But I don't really understand how that works.
So can anyone tell me how I can find a device (the pi's are connect to the WLAN and have a static IP) via an Node-App, e.g. with a search feature or so?
And can I control more then one Raspberry with one App and make the them settings on both devices at the same time?
To get your ip you could use something like this
'use strict';
var os = require('os');
var ifaces = os.networkInterfaces();
Object.keys(ifaces)
.forEach(function (ifname) {
var alias = 0;
ifaces[ifname].forEach(function (iface) {
if ('IPv4' !== iface.family || iface.internal !== false) {
// skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
return;
}
if (alias >= 1) {
// this single interface has multiple ipv4 addresses
console.log(ifname + ':' + alias, iface.address);
} else {
// this interface has only one ipv4 adress
console.log(ifname, iface.address);
}
++alias;
});
});
This outputs following in my case
VirtualBox Host-Only Network 192.168.56.1
Ethernet 192.168.0.101
Ethernet is what you want simply extract the ip part of the string
Now you need this part of ip 192.168.0.
var ping = require ("net-ping");
var ipString = '192.168.0.';
var i = 1;
var session = ping.createSession();
doPing()
function doPing() {
if (i > 254) return;
var ip = ipString + i;
i++;
session.pingHost (ipString + i, function (error, target) {
if (error){
if (error instanceof ping.RequestTimedOutError){
console.log (target + ": Not alive");
doPing();
}
else{
console.log (target + ": " + error.toString ());
doPing();
}
} else {
console.log (target + ": Alive");
doPing();
}
});
}
By now you know all devices that responded to ping so you can use request module to try to connect to web server if there's any running on the device.
Each ping takes a second or 2 so be patient.
This is far from perfect but should work.
I hope it helps

How to calculate node.js socket buffer to avoid allocating memory and never using it?

I'm using node.js as a server between pairs of clients, to handle my online game.
Clients send short messages between hem [one message should not exceed 200bytes].
Currently I expect single client to send [on average] 1 message per second [keeping in mind it can be 5 seconds of nothing and 5 messages one after another].
I've downloaded a sample server using 'net' module and rewritten it to handle the messages the way I need them to be handled.
Basically, for every connected socket, it creates a Buffer with size of 1024*8.
Currently I'm testing my game with some bots, which simply connect, wait 3 seconds and disconnect. They only send 1 message. Nothing else happening.
function sendMessage(socket, message) {
socket.write(message);
}
server.on('connection', function(socket) {
socket.setNoDelay(true);
socket.connection_id = require('crypto').createHash('sha1').update( 'krystian' + Date.now() + Math.random() ).digest('hex') ; // unique sha1 hash generation
socket.channel = '';
socket.matchInProgress = false
socket.resultAnnounced = false;
socket.buffer = new Buffer(cfg.buffer_size);
socket.buffer.len = 0; // due to Buffer's nature we have to keep track of buffer contents ourself
_log('New client: ' + socket.remoteAddress +':'+ socket.remotePort);
socket.on('data', function(data_raw) { // data_raw is an instance of Buffer as well
if (data_raw.length > (cfg.buffer_size - socket.buffer.len)) {
_log("Message doesn't fit the buffer. Adjust the buffer size in configuration");
socket.buffer.len = 0; // trimming buffer
return false;
}
socket.buffer.len += data_raw.copy(socket.buffer, socket.buffer.len); // keeping track of how much data we have in buffer
var str, start, end
, conn_id = socket.connection_id;
str = socket.buffer.slice(0,socket.buffer.len).toString();
if ( (start = str.indexOf("<somthing>")) != -1 && (end = str.indexOf("</something>")) != -1) {
try {
if (!<some check to see if the message format is right>) {
sendMessage(socket, "<error message to the client>");
return;
}
<storing info on the socket>
} catch(err) {
sendMessage(socket, "<error message to the client>");
return;
}
socket.channel = <channel>;
str = str.substr(end + 11);
socket.buffer.len = socket.buffer.write(str, 0);
sockets[socket.channel] = sockets[socket.channel] || {}; // hashmap of sockets subscribed to the same channel
sockets[socket.channel][conn_id] = socket;
waiting[socket.channel] = waiting[socket.channel] || {};
waiting[socket.channel][conn_id] = socket;
sendMessage(socket, "<info message to the client>");
for (var prop in waiting[socket.channel]) {
if (waiting[socket.channel].hasOwnProperty(prop) && waiting[socket.channel][prop].connection_id != socket.connection_id) {
<here I'll try to advertise this client among other clients>
sendMessage(waiting[socket.channel][prop], "<info to other clients about new client>");
}
}
}
var time_to_exit = true;
do{ // this is for a case when several messages arrived in buffer
if ( (start = str.indexOf("<some other format>")) != -1 && (end = str.indexOf("</some other format>")) != -1 ) {
var json = str.substr( start+19, end-(start+19) );
var jsono;
try {
jsono = JSON.parse(json);
} catch(err) {
sendMessage(socket, "<parse error>");
return;
}
if (<message indicates two clients are going to play together>) {
if (waiting[socket.channel][jsono.other_client_id] && waiting[socket.channel][socket.connection_id]) {
delete waiting[socket.channel][jsono.other_client_id];
delete waiting[socket.channel][socket.connection_id];
var opponentSocket = sockets[socket.channel][jsono.other_client_id];
sendMessage(opponentSocket, "<start game with the other socket>");
opponentSocket.opponentConnectionId = socket.connection_id;
sendMessage(socket, "<start game with the other socket>");
socket.opponentConnectionId = jsono.other_client_id;
}
} else if (<check if clients play together>) {
var opponentSocket = sockets[socket.channel][socket.opponentConnectionId];
if (<some generic action between clients, just pass the message>) {
sendMessage(sockets[socket.channel][socket.opponentConnectionId], json);
} else if (<match is over>) {
if (<match still in progress>) {
<send some messages indicating who won, who lost>
} else {
<log an error>
}
delete sockets[socket.channel][opponentSocket.connection_id];
delete sockets[socket.channel][socket.connection_id];
}
}
str = str.substr(end + 20); // cut the message and remove the precedant part of the buffer since it can't be processed
socket.buffer.len = socket.buffer.write(str, 0);
time_to_exit = false;
} else { time_to_exit = true; } // if no json data found in buffer - then it is time to exit this loop
} while ( !time_to_exit );
}); // end of socket.on 'data'
socket.on('close', function(){ // we need to cut out closed socket from array of client socket connections
if (!socket.channel || !sockets[socket.channel]) return;
if (waiting[socket.channel] && waiting[socket.channel][socket.connection_id]) {
delete waiting[socket.channel][socket.connection_id];
}
var opponentSocket = sockets[socket.channel][socket.opponentConnectionId];
if (opponentSocket) {
sendMessage(opponentSocket, "<the other client has disconnected>");
delete sockets[socket.channel][socket.opponentConnectionId];
}
delete sockets[socket.channel][socket.connection_id];
_log(socket.connection_id + " has been disconnected from channel " + socket.channel);
}); // end of socket.on 'close'
}); // end of server.on 'connection'
server.on('listening', function(){ console.log('Listening on ' + server.address().address +':'+ server.address().port); });
server.listen(cfg.port);
I've pasted the above code [very stripped version of the original] to give you and idea about how simple the server is.
I've got an array of sockets, who joined the game and array of sockets on the waiting list, waiting for another client to play with.
Nothing else is going on.
Still the script is memory hungry - 5 hours of connecting and disconnecting gave me this:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31461 ec2-user 20 0 995m 91m 7188 S 0.7 15.4 1:29.07 node
I think this is way too much.
I'm using nodetime.com free service at the moment to monitor the script, but none of the metrics would suggest the script gained so much memory (it starts with just 10-12MB).
I believe this is due to the buffers, and because they allocate too much memory.
I'm only wondering, if my assumptions regarding buffer size are correct.
Should I adjust the buffer to reflect the amount of data I expect from the client?
If I expect the client to send 5 messages with a very short time between them, 200 bytes max each, should I assume that 1024*3 would be enough?
Or should I adjust buffer size according to the message size I expect, so if I'm sure the message will never go above 300 bytes, I should be fine with buffer size of 512?
Thanks,
Krystian
EDIT:
Node version:
$ node -v
v0.10.5
$ npm -v
1.2.19
EDIT2:
I've tested the script with 400 connections connecting and disconnecting and memory usage dropped significantly to around 60MB. After changing the test setup back to 4 connections it went up again.
The kernel has a socket receive buffer which is at least 8k., which takes care of multiple incoming messages on the socket. You don't need to buffer messages you've already read, so your application buffer doesn't need to be any bigger than the largest expected message.

Why does the Node.js scripts console close instantly in Windows 8?

I've tried nearly every example for scripts I can find. Every sample opens the terminal for a split second. Even this closes as soon as input is entered. Is this normal?
var rl = require('readline');
var prompts = rl.createInterface(process.stdin, process.stdout);
prompts.question("How many servings of fruits and vegetables do you eat each day? ", function (servings) {
var message = '';
if (servings < 5) {
message = "Since you're only eating " + servings +
" right now, you might want to start eating " + (5 - servings) + " more.";
} else {
message = "Excellent, your diet is on the right track!";
}
console.log(message);
process.exit();
});
There are 2 options that control this in Tools/Options/Node.js Tools/General:
Wait for input when process exists abnormally
Wait for input when process exists normally
Taken from https://nodejstools.codeplex.com/discussions/565665

Scala Process exits but doesn't clean up threads

I am trying to run PhantomJS from within a scala application using akka actors:
val process = Process("phantomjs --ignore-ssl-errors=yes " + myrenderscript.js + args ...)
val result = process.run(processLogger, true).exitValue() match {
case ExitCode.SUCCESS => Left(Success)
case ExitCode.TIMEOUT => Right(TimeoutError)
case ExitCode.OPEN_FAILED => Right(NetworkError)
case _ => Right(UnknownError)
}
the myrenderscript.js looks like this:
var version = "1.1";
var TIMEOUT = 30000,
EXIT_SUCCESS = 0,
EXIT_TIMEOUT = 2,
EXIT_OPEN_FAILED = 3;
if (phantom.args.length < 2) {
console.log("Usage: phantomjs render.js parentUrl output [width height]");
phantom.exit(1);
}
var url = phantom.args[0];
var output = phantom.args[1];
var width = parseInt(phantom.args[2] || 1024);
var height = parseInt(phantom.args[3] || 1024);
var clipwidth = parseInt(phantom.args[4] || 1024);
var clipheight = parseInt(phantom.args[5] || 1024);
var zoom = parseFloat(phantom.args[6] || 1.0);
var phantom_version = phantom.version.major + "." + phantom.version.minor + "." + phantom.version.patch;
var userAgentString = "PhantomJS/" + phantom_version + " screenshot-webservice/" + version;
renderUrlToFile(url, output, width, height, clipwidth, clipheight, zoom, userAgentString, function (url, file) {
console.log("Rendered '" + url + "' at size (" + width + "," + height + ") into '" + output + "'");
phantom.exit(EXIT_SUCCESS);
phantom = null;
});
setTimeout(function () {
console.error("Timeout reached (" + TIMEOUT + "ms): " + url);
phantom.exit(EXIT_TIMEOUT);
}, TIMEOUT);
function renderUrlToFile(url, file, width, height, clipwidth, clipheight, zoom, userAgentString, callback) {
console.log("renderUrlToFile start: " + url)
var page = new WebPage();
page.viewportSize = { width: width, height: height };
page.clipRect = { top: 0, left: 0, width: clipwidth, height: clipheight};
page.settings.userAgent = userAgentString;
page.zoomFactor = zoom;
page.open(url, function (status) {
console.log("renderUrlToFile open page: " + url)
if (status !== "success") {
console.log("Unable to render '" + url + "' (" + status + ")");
page.release();
page.close();
page = null;
phantom.exit(EXIT_OPEN_FAILED);
} else {
console.log("renderUrlToFile open page success and pre-render: " + url)
page.render(file);
console.log("renderUrlToFile open page post-render: " + url)
page.release();
page.close();
page = null;
callback(url, file);
}
});
}
prior to creating the process and after it finishes running, about 4 new threads are being created.
Each time the method that creates the process is called, new threads are created and started. After the process is done, the threads go back to a state of monitoring. Eventually my application takes upwards to 500+ threads (I'm capturing a large website and the internal links)
How do I get scala to clean up the threads that are created when running phantomjs?
Edit:
I've changed the scala code to do the following:
val process = Process("phantomjs --ignore-ssl-errors=yes " + myrenderscript.js + args ...).run(processLogger, connectInput)
val result = process.exitValue() match {
case ExitCode.SUCCESS => Left(Success)
case ExitCode.TIMEOUT => Right(TimeoutError)
case ExitCode.OPEN_FAILED => Right(NetworkError)
case _ => Right(UnknownError)
}
process.destroy()
Yet still the threads live on....
I figured out why it is not cleaning up the threads but I don't fully understand it. So if someone posts the true answer on here, I'll vote that answer up.
The problem was I was setting the connectInput value to true. When I set it to false, the threads get destroyed as expected. I'm not sure as to why.
When set to true, a thread dump reveals that one of the threads was blocking the others:
Thread-3#2830 daemon, prio=5, in group 'main', status: 'RUNNING'
blocks Thread-63#4131
blocks Thread-60#4127
blocks Thread-57#4125
blocks Thread-54#4121
blocks Thread-51#4103
blocks Thread-48#4092
blocks Thread-45#4072
blocks Thread-42#4061
blocks Thread-39#4054
blocks Thread-36#4048
blocks Thread-33#4038
blocks Thread-30#4036
blocks Thread-27#4008
blocks Thread-24#3996
blocks Thread-21#3975
blocks Thread-18#3952
blocks Thread-15#3939
blocks Thread-12#3905
blocks Thread-9#3885
blocks Thread-6#3850
at java.io.FileInputStream.readBytes(FileInputStream.java:-1)
at java.io.FileInputStream.read(FileInputStream.java:220)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at java.io.FilterInputStream.read(FilterInputStream.java:90)
at scala.sys.process.BasicIO$.loop$1(BasicIO.scala:225)
at scala.sys.process.BasicIO$.transferFullyImpl(BasicIO.scala:233)
at scala.sys.process.BasicIO$.transferFully(BasicIO.scala:214)
at scala.sys.process.BasicIO$.connectToIn(BasicIO.scala:183)
at scala.sys.process.BasicIO$$anonfun$input$1.apply(BasicIO.scala:190)
at scala.sys.process.BasicIO$$anonfun$input$1.apply(BasicIO.scala:189)
at scala.sys.process.ProcessBuilderImpl$Simple$$anonfun$2.apply$mcV$sp(ProcessBuilderImpl.scala:72)
at scala.sys.process.ProcessImpl$Spawn$$anon$1.run(ProcessImpl.scala:22)
I initially thought it was the process logger, but that wasn't the case.
Can someone explain this to me?

PhantomJS: how to type text to a textbox?

The only solution I can think of is to do it with JS, but I can't pass any variables from the phantom script to the JS I'm trying to execute.
You should take a look at CasperJS. It's a very nice PhantomJS script that allows you to easily perform this kind of web behavior.
As far as communicating with your PhantomJS script, as stands today, you have a few reliable options:
Pass your data in via command line args.
Exchange data via reading/writing of files.
Have your PhantomJS script call your Node.js script via GETS/POSTS.
Yes, there are issue in the QtWebKit bridge between C++ and JS to pass stuff up and down.
It works, but better from JS to C++ than the opposite.
We have a number of issues to address, but this is one of the highest in number one in terms of demand.
In the meanwhile, I usually "decorate" the page object like this:
var page = require("webpage").create();
page.evaluateWithParams = function(func) {
var args = [].slice.call(arguments, 1),
str = 'function() { return (' + func.toString() + ')(',
i, ilen, arg;
for (i = 0, ilen = args.length; i < ilen; ++i) {
arg = args[i];
if (/object|string/.test(typeof arg)) {
str += 'JSON.parse(' + JSON.stringify(JSON.stringify(arg)) + '),';
} else {
str += arg + ',';
}
}
str = str.replace(/,$/, '); }');
return this.evaluate(str);
}
And then you can call a function within the scope of the page like this:
var a = 1, b = 2;
page.evaluateWithParams(function(arg1, args) {
// your code that uses arg1 and arg2
}, a, b);
Hope this helps.
Ivan

Resources