TAG:
Creating a TCP Ping Echo on User-Defined Protocols -------------------------------------------------------------------------------- This article was contributed by Alumni. Environment: Internet, networking Downloads Download demo program - 24 Kb 点击浏览该文件 Download source - 2 Kb 点击浏览该文件 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. History Date Posted: May 13, 2003 (Alumni) |