CodeGuru content and product recommendations are
editorially independent. We may make money when you click on links
to our partners.
Learn More
Environment:Internet, networking
TCP Ping is necessary when measuring server functionality from different IP networks (mirror sites). As you see, it uses a TCP transport protocl instead of ICMP. To ping the remote (or local) server, it should be able to provide “NOOP” command (NO OPeration) followed by CRLF.
Such user-defined protocols can be:
- SMTP/25;
- FTP/21;
- POP3/110;
- and so forth (NOOP implemented).
Options included in demo project are the following:
- -cv: Connective ping (default)
- -ct: Continuous ping
- -n: Specify NOOP command
- -crlf: Append CRLF to NOOP
- -t<t>: Specify timeout
Hence, you can specify NOOP command yourself, of course, if it differs from the default.
The reasonable question: How do you ping the HTTP server? To ping the HTTP server, you should specify a NOOP-command (because it’s not implelemented in HTTP/1.x) as the implemented method. This time, a connective ping is better than a continuous ping. Let’s see the connective ping source:
unsigned int CPing::PingConnective(char* szHost,
unsigned int iPort,
unsigned int iPackets)
{
struct hostent* host = NULL;
struct sockaddr_in saddr;
unsigned int s = 0;
unsigned int dw1, dw2, dw3;
char szBuffer[256];
if (iPackets>MAX_SENDS) return (0);
free (Res);
Res = (pingstore*)malloc (sizeof(pingstore)*iPackets);
memset (Res, 0, sizeof(pingstore)*iPackets);
if (!iBytesToRecv) iBytesToRecv = strlen(szNoop);
host = gethostbyname (szHost);
if (host==NULL) return (0);
saddr.sin_family = AF_INET;
saddr.sin_port = htons(iPort);
saddr.sin_addr = *((struct in_addr*)host->h_addr);
for (int i=0;i< iPackets;i++)
{
s = socket(AF_INET, SOCK_STREAM, 0);
if (!s) return ((iTotalRes)?1:0);
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
(char*)&iTimeOut, sizeof(iTimeOut));
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO,
(char*)&iTimeOut, sizeof(iTimeOut));
if (connect (s,(struct sockaddr*)&saddr, sizeof(saddr))
== -1) return ((iTotalRes)?1:0);
iTotalRes++;
sprintf (szBuffer, "%srn", szNoop);
dw1 = GetTickCount();
int iSent = send (s, szBuffer, strlen(szBuffer), 0);
dw2 = GetTickCount();
int iRecv = recv (s, szBuffer, iBytesToRecv, 0);
dw3 = GetTickCount();
Res[i].iPort = iPort;
Res[i].iTimeSend = dw2-dw1;
Res[i].iTimeRecv = dw3-dw2;
Res[i].iTotalSent = ((iSent==SOCKET_ERROR)?0:iSent);
Res[i].iTotalRecvd = ((iRecv==SOCKET_ERROR)?0:iRecv);
closesocket (s);
}
return (1);
}
You can use a simple Perl script for it:
#!/usr/local/bin/perl
# ################################
# Connective ping to http-server
# ################################
die("httpping.pl <host> <packets> [-p<port>]n")
unless (scalar(@ARGV)>=2);
$host = $ARGV[0];
$port = 80; # default, but you can change it
$packets = $ARGV[1];
$noop = "GET / HTTP/1.0";
for ($i=2; $i< scalar(@ARGV);$i++)
{
if ($ARGV[$i] =~ /^(x2Dx70)/)
{
$port = substr ($ARGV[$i],2,length($ARGV[$i])-2);
}
}
open (PING, "|ping.exe $host $port $packets -n -cv -crlf") ||
die ("Error: ping executable not foundn");
print PING "$noopn";
close (PING);
Example of Usage
> ping localhost 8080 10 -n -crlf -cv
Enter valid NOOP command: GET / HTTP/1.0
...
In conclusion, note that you can also modify the timeout value to extend or lower the “live time” of requests. I hope this will be very helpful for system administrators to audit their systems on “request-response” ability.
Downloads
Download demo program – 24 Kb
Download source – 2 Kb