Check out the new USENIX Web site. next up previous
Next: Canvas Improvements Up: Experiences Previous: Experiences

Sockets between Heterogeneous Platforms

When this work began, sockets were not an official part of Tcl 7.3 and Tk 3.6. It is partly for this reason that the specification for interprocess communication between simulator and display uses binary data and not strings, which would be more natural for Tcl. Nonetheless, we retrofitted both the simulator and display to use Tcl sockets when they became available in Tk 4.1. Taking advantage of the cross-platform advances in Tcl/Tk 8.0 has allowed us to port both the simulator and the display to various platforms on which Tcl is supported. Both applications should be capable of running on any Tcl-supported platform and have been tested successfully on Solaris 2.x, MacOS 8.x, and MkLinux DR3 on a PowerPC.

Despite the uniform, cross-platform access to sockets that Tcl provides, problems arise when the simulator is run on one architecture and the display is run on another. When both applications are run on the same architecture, each safely interprets incoming binary data in its native format. However, when one application is run on a little endian architecture (e.g., Windows on x86 processors) and the other is run on a big endian architecture (e.g., Solaris on SPARC processors), this is no longer the case. When one interprets an integer sent by the other, the receiver will ``see'' the integer as a different value than the sender intended because the ordering of the bytes comprising the four-byte integer are stored (and therefore transmitted) in a different order. A similar situation occurs with the Thunder and Lightning switch processor, which uses a non-standard floating point format for efficiency.

The binary socket option combined with the binary command in Tcl 8.0 provides only a partial solution to this problem. Using the binary command, integer data can be converted to a known byte ordering, and the simulator and display could each convert from the agreed upon order to their platform's native order. However, the binary command cannot be used in this way for floating point data, which is used by other display modules. In addition, the binary command would be unavailable for use within the Thunder and Lightning switch processor, as the daemon does not have access to a Tcl interpreter.

Instead, we solved this binary data representation problem by using the XDR (external data representation) standard, which imposes a common network byte ordering (and size) for all simple data types. XDR provides functions of the form xdr_type for encoding or decoding data of type type. The preceding section presented code examples using the function xdr_int to read integers from an XDR buffer. Because all data exchanged between simulator and display are converted into network form by XDR routines, we are guaranteed that there will be no ``misunderstanding'' between the two.

Figure 8: General template for creating XDR functions for simple data types on big endian architectures.
\begin{figure*}
\footnotesize\vspace*{0.05in}
{\it enum} xdr\_direction \{XDR\_D...
...backslash$\ \\
\> \> {\it return} 1; $\backslash$\ \\
\} \\
\par\end{figure*}

Unfortunately, XDR is not available on every Tcl-supported platform. Most UNIX variants support XDR because it is used by RPC, but the MacOS is one platform without XDR support. To enable compilation on the Macintosh platform, we have had to implement the XDR routines we use. As most simple data types are already in network form, we can simply use the C macro shown in Figure 8 to create the missing XDR functions for most datatypes. For example, the simple macro invocation easyxdr(long) will define the C function xdr_long, which converts long integers to and from network form.

Although implementing XDR functionality on big endian architectures such as the MacOS is relatively straightforward, more work is required to implement XDR on a little endian architecture. Because the typical Tcl/Tk programmer should not have to worry about such differences in a cross-platform language such as Tcl, we strongly believe that XDR should be incorporated into the Tcl language. With the introduction of sockets, Tcl has provided an elegant, uniform interface to the differing TCP/IP stacks on the various Tcl-supported architectures. The addition of XDR (or a similar network byte-order standard for all primitive data types) would provide seamless interplatform communication and thereby greatly extend the power of the Tcl socket abstraction.

There are several ways in which XDR could be incorporated into Tcl. The most obvious is an xdr Tcl command similar to the binary command added in Tcl 8.0. Encoding an integer could then be as simple as executing a command such as set dataToSend [xdr encode integer $myInteger]. Decoding a message would require reading the message into a buffer (string) and executing a command such as set decodedInt [xdr decode integer myBuffer]. Note that the xdr command must consume data from myBuffer so the variable name and not its value must be passed.

Another alternative for incorporating XDR would be to use a method similar to the stream filters provided by TclDP [5]. TclDP allows the user to register a filter mechanism with a Tcl channel such that all reads and writes for the channel first pass through the filter. TclDP filters are very flexible and work well when all data passing through the channel must be transformed in the same way (e.g., uuencoding). However, XDR data are processed differently depending on the type of data the user wishes to read from the channel. Unless the filter procedure knows in advance the kind of data to be read, TclDP filters don't help with XDR. Instead, we need a mechanism that allows the user to pass a filter to each read/write call on the channel. For example, to read an XDR-encoded integer from the channel, we would call the channel read procedure, instructing it to use the integer XDR filter. This would result in exactly four bytes being read from the channel, and the returned data buffer would contain one XDR-decoded integer. Of course, Tcl would still have to provide XDR filter functions for each of the standard C types, but implementing XDR in this way would also provide the general flexibility of TclDP filters.


next up previous
Next: Canvas Improvements Up: Experiences Previous: Experiences
Michael Santos
1998-07-27