Computer Nodes Interlinked by TCP/IP
Running Behind Firewalls
The most common way to interlink computers via the Internet is using the TCP/IP protocol. Java's core API is well-designed for developing standard socket-based client-server applications, so an extra library layer for TCP/IP communication seems to be an overkill. The situation becomes more complicated if the hosts are protected by firewalls. In a typical situation (computers in a campus PC pool, inside an enterprise building, etc.) the clients are restricted solely to outgoing HTTP connections via IP port 80. The TcpJLib framework presented here allows you to interlink hosts located in a firewall-protected site and develop typical stream-based multitclient-server applications using a HTTP tunneling technique: A server using port 80 acts as a relay between nodes somewhere else, even if they are protected by firewalls. Seen from the network, the relay server looks like a standard HTTP server and the nodes connects as standard HTTP clients.
Standard socket connections use streams for transfering data. After a TCP client connects to a server, input and output streams remain open until the socket is closed. Using the HTTP protocol here causes another problem: The HTTP protocol is stateless, e.g. that a client performs a HTTP GET request to the server and the server opens a socket connection. Now the server replies by sending some data back to the requesting client and closes the socket. The socket may also be closed by the firewall that protects the server and admits only traffic that conforms to the HTTP protocol. With TcpJLib the relay server and the nodes are connected by a continuously opened up and down stream as long as you like. This is realized by feinting the network as if a long WAV file were up- and downloaded. Keep-alive data is transferred at an interval of about 1 second completely transparent to the user. Moreover this trick allows the relay to detect if a node fades away. The relay will send connecting and disconnecting messages down to all TcpNodes as a status notification. The nodes are identified by a nickname that they send to the relay while connecting. The relay handles name clashs by appending number tags.
Despite, seen from the network, a TcpJLib node is a HTTP client, logically it may act as a server as well as a client. We call the node a bridge when it acts as a server and call it an agent when it acts as a client. Obviously using a bridge and any number of agents you can develop a multi-client/server topology completely free of firewall constraints.
The relay server is part of the TcpJLib distribution. It is session-oriented, e.g. any number of bridge/clients-applications (up to a maximum for security reasons) may use its service in parallel by specifying a unique session ID. The relay IP must be known to all participants, so it should run with a fixed IP address or with a fixed IP alias that is DNS mapped to the current IP address. When you use the TcpJLib library in default mode, you are automatically linked through our relay server clab3.phbern.ch located in Bern, Switzerland.
TcpJLib is specially designed to develop multiuser game application with one game server and several game clients. Because for security reasons we do not want to relay binary data with high bandwidth, TcpJLib is not designed for game applications where updating the game state needs high data rates. In a typical game application suitable for TcpJLib, only few data is transferred each time the player makes a move. Despite the data streams are continuously open, we restrict the data type to ASCII character arrays (ASCII strings terminated with newline character). For many game applications the game state may be transferred using a command tag followed by some state values. Because both may be easily coded using integers, TcpJLib provides the classes TcpBridge and TcpAgent specially designed for integer data transfer.
Design principle explained by examples
The first example shows how extremely simple it is to exchange data between nodes connected in the same session. A node connects to the TcpRelay by calling connect() passing a session ID and a nickname. The relay opens a new session if there is no other node in the same session. After connection the node sends a line of text by calling sendMessage(). This message is sent to all nodes connected in the same session. When a node receives a message or a status information, the callback messageReceived() resp. statusReceived() is triggered.
Execute the program locally using WebStart. You may start several program instances from the same or different computers with the same session ID and nickname.
In the following slightely more complicated example 10 random numbers are sent to all nodes whenever the user of any node strikes a key.
Execute the program locally using WebStart.
You may start any number of program instances. All nodes with the same session ID shares the data exchange. The code is almost self-explaining, but please pay attention to the following points:
Using the same technique it is easy to develop a fully functional Internet chat application with any number of participants in any number of rooms. All you need in addition to TcpJLib is some basic knowledge of GUI construction using Swing. (Pay attention to use ASCII characters only.)