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 # connective ping
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.