The SWANS transport entity receives upcalls from the network entity with packets of the appropriate network protocol and passes them on to the appropriate registered transport protocol handler. It also receives downcalls from the application entity, which it passes on to the network entity. The two implemented transport protocols are UDP and TCP, which encapsulate packets with the appropriate packet headers. UDP socket, TCP socket and TCP server socket implementations actually exist within the application entity. The primary reason for this decision is that these implementations are modeled after corresponding Java classes, which force the use non-timeless objects. The DatagramSocket, for example, uses a mutable DatagramPacket to provide data. In all other respects, including correctness and performance, this decision, to move the socket implementations into the application entity, is inconsequential.
SWANS installs a rewriting phase that substitutes identical SWANS socket implementations for the Java equivalents within node application code. This allows existing Java networking applications to be run as-is over the simulated SWANS network. The SWANS implementations use continuations and a blocking channel in order to implement blocking calls. The entire application is conveniently frozen, for example, at the point that it calls receive until its packet arrives through the simulated network. Thus, we have a powerful Java simulation ``sandwich'': Java networking applications running over SWANS, running over JiST, running within the JVM.
There is an interesting complexity in this transformation that is worth mentioning. As discussed previously, since constructors can not be invoked twice, they may not be continuable. However, certain socket constructors, such as a TCP socket, have blocking semantics, since they require a connection handshake. We circumvent this problem by rewriting constructor invocations into two separate invocations. The internal socket implementation has a non-blocking constructor, which does nothing more than store the initialization arguments and a second blocking method that will always be called immediately after the constructor. This second method can safely perform the required blocking operations.
|TransInterface||TransUdp||UDP implementation, usually interacts with jist.swans.app.net.UdpSocket.|
|TransTcp||TCP implementation, usually interacts with jist.swans.app.net.TcpServerSocket and .TcpSocket and various blocking streams implementations in jist.swans.app.io.*|