#include <base/Application.h>
#include <base/Timer.h>
#include <base/UnsignedInteger.h>
#include <base/math/Math.h>
#include <base/net/StreamSocket.h>
#include <base/net/InetInterface.h>
#include <base/net/InetService.h>
#include <base/net/InetEndPoint.h>
#include <base/concurrency/Thread.h>
#include <base/string/FormatOutputStream.h>
#include <base/string/StringOutputStream.h>
using namespace com::azure::dev::base;
private:
static const unsigned int MAJOR_VERSION = 1;
static const unsigned int MINOR_VERSION = 0;
static const unsigned short ECHO_SERVICE_PORT = 7;
unsigned short port = 0;
unsigned int dataSize = 0;
unsigned int timeout = 0;
unsigned int packetsToTransmit = 0;
enum Command {
COMMAND_HELP,
COMMAND_VERSION,
COMMAND_PING
};
public:
PingApplication()
{
port = ECHO_SERVICE_PORT;
dataSize = 32;
timeout = 1000000;
packetsToTransmit = 0;
}
void onTermination() noexcept {
}
String getTimeAsString2(uint64 microseconds) noexcept {
}
String getTimeAsString(uint64 microseconds) noexcept {
if (microseconds < 1000) {
stream << microseconds << "us";
} else if (microseconds < 1000000) {
stream << FIXED
<< setPrecision(3) << microseconds/1000.0 << "ms";
} else {
stream << FIXED
<< setPrecision(3) << microseconds/1000000.0 << "s";
}
stream << FLUSH;
}
void ping(
const String& host) noexcept {
bool byName = true;
try {
ferr << "Error: " << "Unable to resolve host." << ENDL;
setExitCode(EXIT_CODE_ERROR);
return;
}
try {
} catch (...) {
}
if (byName) {
fout << "Pinging " << name << ' ' << '(' << address << ')' << " with "
<< dataSize << " bytes of data" << EOL
<< ENDL;
} else {
fout << "Pinging " << ' ' << '(' << address << ')' << " with "
<< dataSize << " bytes of data" << EOL
<< ENDL;
}
try {
ferr << "Error: " << "Unable to connect." << ENDL;
setExitCode(EXIT_CODE_ERROR);
return;
}
unsigned int packetsTransmitted = 0;
unsigned int packetsReceived = 0;
uint64 maximumTime = 0;
uint64 totalTime = 0;
while (!isTerminated() &&
((packetsToTransmit == 0) ||
(packetsTransmitted < packetsToTransmit))) {
*dest++ = packetsTransmitted;
++packetsTransmitted;
unsigned int bytesAvailable = socket.
available();
if (bytesAvailable < incoming.
getSize()) {
fout << name << ' ' << '(' << address << ')'
<< ':' << " request timed out" << ENDL;
} else {
while (bytesAvailable >= incoming.
getSize()) {
++packetsReceived;
<< " bytes from " << name << ' '
<< '(' << address << ')' << ':' << ' '
<< "n=" << packetsReceived << ' '
<< ENDL;
break;
}
}
}
}
}
unsigned int packetsLost = packetsTransmitted - packetsReceived;
double meanTime = (packetsReceived > 0) ? totalTime/packetsReceived : 0;
fout << EOL
<< "--- statistics for " << name << " ---" << EOL
<< "Packets transmitted: " << packetsTransmitted << EOL
<< "Packets received: " << packetsReceived << EOL
<< "Packets lost: " << packetsLost << ' '
<< '(' << static_cast<int>((packetsTransmitted > 0) ? (100*packetsLost/packetsTransmitted) : 0) << '%' << ')' << EOL
<< "Time minimum/maximum/mean: "
<< getTimeAsString(minimumTime) << '/'
<< getTimeAsString(maximumTime) << '/'
<< getTimeAsString(static_cast<uint64>(meanTime)) << EOL
<< ENDL;
}
void version() noexcept
{
fout << getFormalName() << " version "
<< MAJOR_VERSION << '.' << MINOR_VERSION << EOL
<< "The Base Framework (Test Suite)" << EOL
<< ENDL;
}
void help() noexcept
{
version();
fout << getFormalName()
<< " [--help] [--port PORT] [--data SIZE] [--time MS] host" << ENDL;
}
void main()
{
Command command = COMMAND_PING;
while (enu.hasNext()) {
if (argument == "--help") {
command = COMMAND_HELP;
break;
} else if (argument == "--version") {
command = COMMAND_VERSION;
break;
} else if (argument == "--port") {
try {
if (value > 0xffff) {
ferr << "Error: " << "Invalid port" << ENDL;
setExitCode(EXIT_CODE_ERROR);
return;
}
port = value;
try {
setExitCode(EXIT_CODE_ERROR);
return;
}
}
} else {
host = argument;
}
}
}
ferr << "Error: " << "Host not specified" << ENDL;
setExitCode(EXIT_CODE_ERROR);
return;
}
switch (command) {
case COMMAND_HELP:
help();
break;
case COMMAND_VERSION:
version();
break;
case COMMAND_PING:
ping(host);
break;
}
}
};
APPLICATION_STUB(PingApplication);