[ Go to May 1997 Table of Contents ]|
Internet Ping Pong
Test your connection speed by bouncing packets back-and-forth across the Web.
When WINDOWS Magazine's top brass asked me to build a Web page that tests connection speeds across the Internet, I realized I had my work cut out for me.
Naturally, the Web page would use a ping (Packet Internetwork Groper) program, which sends time-stamped, echo-request packets to an IP address and notes when the reply arrives. The difference between the original time stamp and the reply time stamp is defined as the RTT (round trip time). The echo-request packets use ICMP, the Internet Control Message Protocol. Nearly all computers with TCP/IP installed will respond to such requests-as long as the packets aren't too long and aren't sent in abusive quantities.
The way I figured it, there were at least three ways to implement such a page: via a CGI (Common Gateway Interface) script, Java applet or ActiveX control. The CGI script would run on the Web server, ping the user's computer from the server and report the RTT on a dynamic Web page. The Java applet and ActiveX control, by contrast, would run on the client, ping the server (or any other site on the Internet) and display the RTT on a "live" part of the browser display.
For this project, I decided to build a client-side program because it lets you ping multiple sites. Next, I had to choose between writing a Java applet or an ActiveX object. I had my answer once I checked the java.net class. That's when I discovered ICMP requests are not supported, so I built an ActiveX object instead.
As I've discussed several times (for instance, visit http://www.techweb.com/activexpress/), ActiveX is a grab-bag Microsoft trademark that encompasses several different technologies. A minimal ActiveX object supports COM (Component Object Model) interface queries and reference counting-the Iunknown interface. A more convenient ActiveX object-accessible from a scripting language-also supports OLE Automation, which implies IDispatch interface and perhaps a type library. A full-blown ActiveX control supports all of that plus another dozen interfaces: It's an actual visible control that can display itself inside a container.
To produce automation objects with small footprints suitable for downloading, Microsoft's principal offering is the ActiveX Template Library (ATL). It's available at http://www.microsoft.com/visualc/v42/atl/and requires Visual C++
Once you've installed the ATL, its ATL COM AppWizard can help you create a new project workspace in Visual C++. The AppWizard generates the IDL, CPP, H, DEF and MAK files for an OLE Automation server to your specifications. For this example, I created an in-process (DLL) server with one Pinger object containing one dual interface and simple registration support.
The code generated by the AppWizard doesn't know about your own methods, so you'll have to insert them manually. For this project it was only a matter of adding two lines to PING.IDL. After the import statement in the interface IPinger:IDispatch section, I added:
("Returns RTT between user and host sites.")
HRESULT Ping([in] BSTR site,[out, retval] long* retval)
To match this interface definition, I added a new public method STD
METHODIMP CPinger::get_Ping BSTR site,long* retval) to PINGER.CPP and PINGER.H. The Ping method in the Ipinger interface requires a get_Ping C++ method in the CPinger class because the interface method has the propget attribute. I could have defined separate methods to set the various properties, do the actual pinging and get the results, but I chose to keep the methods as simple as possible.
A word to the wise: I learned the hard way that if you change your IDL interface, you have to rebuild your entire project. Just doing a minimal build won't automatically refresh the type library, and the object will reregister itself with the old interface, causing your test code to fail.
When you're ready to call your object from a Web page, you'll need to create an object tag with a class ID in HTML. There are three UUIDs (Universally Unique IDs) in the IDL file for an OLE Automation object: The first is for the interface, the second is for the type library and the third (the one you want to use in HTML code) is for the class.
I considered building my Pinger object using some Sockets 2.0 sample code in the current Win32 software development kit (SDK), but I soon had to change course. I was a little miffed to discover that Sockets 2.0 isn't yet implemented in any released Windows version.
There's actually a special DLL in Windows named ICMP.DLL for implementing ping. It has three functions: one to open an ICMP handle, one to send an ICMP packet and return the response(s), and one to close the ICMP handle. Even so, I still had to write a few hundred lines of code to resolve the host name, fill out the ICMP echo request packet and decode the ICMP echo response packet. You'll find the code for this on my Web page (http://www.winmag.com/people/mheller/)
When I tested my Pinger object on a Web page, I discovered Internet Explorer 3.0x really does check objects before installation. I couldn't install my control with the IE active content security level set high; I had to lower my security to medium. Even then, IE complained that my object was unsigned and made me verify that installing the DLL was acceptable.
I got past that issue by signing my code. At the time, I didn't have an X.509 Software Publishing Certificate (SPC), so I applied for one by visiting http://digitalid.verisign.com/codesign.htm with IE. I applied for a Class 2 certificate (for individual software publishers). It costs $20 annually. You must supply your name, street address, social security number, e-mail address and a valid credit card number. Verisign cross-checks the information against consumer databases. I got my certificate about an hour after I applied. A Class 3 certificate (for multiple developers in the same company) costs $400 annually. Verisign checks the Class 3 application information against your records with Dun & Bradstreet; I'm told that can take two weeks.
The Microsoft ActiveX SDK includes a code signing toolkit that lets you sign your code with your SPC. This toolkit also comes with Visual C++ and Visual J++. Use the toolkit's SignCode program, your SPC and your private key (generated by IE when you apply for your SPC) to add a certificate to your DLL (or EXE, OCX or CAB). You can check the results with the PeSigMgr and ChkTrust programs that come with the ActiveX SDK. The other two programs in the toolkit, MakeCert and Cert2SPC, are strictly for internal testing-you can't use the certificates they create to sign objects you distribute to others. For more information on code signing and safety marking, see http://www.microsoft.com/intdev/controls/signmark.htm.
Signing my object didn't end all the warning boxes. When I tested my object on a Web page using VBScript, IE warned that my object wasn't marked safe for scripting. Fixing this problem is a matter of adding a little code to the object, which you can find in the aforementioned signmark.htm and in the Safety API section of the ActiveX SDK help file.
Safe for scripting
There are two mechanisms for designating an object as safe for scripting: You can write a registry entry that adds the object to the CATID_SafeForScripting category, or you can implement the IObjectSafety interface in your object. I chose to use the registry; adding the code to my DLLRegisterServer function was a brief cut-and-paste job once I found the appropriate snippets. At long last, I had my object working.
By now, you're probably wondering if there will ever be an easier way to build OLE Automation objects. Microsoft's forthcoming Visual C++ 5.0 might just be the answer.