Creating a TCP Ping Echo on User-Defined Protocols

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, "%s\r\n", 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] =~ /^(\x2D\x70)/)
  {
    $port = substr ($ARGV[$i],2,length($ARGV[$i])-2);
  }
}

open (PING, "|ping.exe $host $port $packets -n -cv -crlf") ||
              die ("Error: ping executable not found\n");
print PING "$noop\n";
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.

Downloads

Download demo program - 24 Kb
Download source - 2 Kb


Comments

  • Error in the code

    Posted by Ulfen on 05/21/2004 10:25am

    There is a small error in the code:

    s = socket(AF_INET, SOCK_STREAM, 0); if (!s) ...

    s == 0 could be a valid socket, so the check should be:

    if (s == SOCKET_ERROR) ...

    Reply
  • How can i messure the signal of the current interfaces xxx b/s ?

    Posted by Legacy on 12/19/2003 12:00am

    Originally posted by: mathabu

    best regards

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • Live Event Date: October 29, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this eSeminar, Gene Kim will discuss these survey findings and will share woeful tales of artifact management gone wrong! Gene will also share examples of how …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds