Programs->Java->Sockets package
Sockets Package
Home
  What's New
  Downloads
Programs
  CSS Editor
  TCP/IP
  rInstaller
  R
  R2
  Java
    Bridge
    Sockets package
      XSocket
      XServerSocket
      SocketWatcher
      SocketWatched
Publications
  ODBC Browser
  Internet Server

Red Corona
Mail me




Introduction to Sockets

Sockets are the Java interface to TCP/IP. They can be used to forge connections between two computers for the transfer of data between them. A TCP/IP connection requires two sockets: a client socket and a server socket. The basic difference between them is that a server socket waits for incoming conections, while a client socket actively seeks out a server to connect to.

In my sockets package, these two types of socket are implemented by the two classes XSocket and XServerSocket, and the XServerSocket produces new XSocket objects when a new connection is made.

As it is the more common type, I will discuss client sockets (i.e. the XSocket class) first.

Client Sockets

Client sockets are implemented by the XSocket class. To connect to a server, use the commonest constructor for XSocket, which is:
new XSocket(String host, int port)
This hopefully means that the XSocket connects to the server on the right port. If it doesn’t, the constructor throws a java.io.IOException, so this leads to code like this:
try{
sock = new XSocket("219.64.5.12", 1000);
} catch(java.io.IOException e){System.out.println("Could not connect to server");

Once the socket has been opened, you can read and write data from it. The four types of data function are listed below:

  • byte: readByte() and writeByte(byte)
  • byte[]: readBytes(number of bytes) and writeBytes(byte[])
  • int: readInt(number of bytes); no writeInt() yet
  • String: readString() and writeString(String)
For readString(), the entire content of the socket’s data stream are put into the string – it is your responsibility to sort out the packets from each other. For all these methods, a -2 signifies that there is not enough data available, and a -1 means the server closed the connection. Write methods just push the input down the socket.

Read and write methods can throw a java.io.IOException if it all goes wrong, so you should wrap a try...catch around calls to them.

To find out if any data is available, use the method ready() (true = some data, false = no data); to find out how much is available, use available() which returns an int. To skip over some data, use skip(int len), which ignores len bytes.

Client Notification

But what if you want to be told, or notified, when data arrives in the socket. For this, you have to implement the SocketWatcher interface and add yourself to the SocketWatched object associated with the XSocket. For example, the code fragment:
import util.*;
public class SockTest implements SocketWatcher{
XSocket sock;
... main() and suchlike go here ...
public void sockInit(){
try{sock = new XSocket("180.254.0.8", 80);}
catch(java.io.IOException e){}
sock.obs.add(this);
This line is the important one
}
} // end of class

... will add the class to the SocketWatched object for sock. The line
sock.obs.add(this);
should be added to every class that wants notification of data reception. In every XSocket, there is a variable obs containing a SocketWatched object, which is notified when the XSocket receives data. By calling the add() method of obs, you get the SUpdate method (see below) called when it does.

But this is not enough. The SocketWatcher interface requires two methods to be implemented. These are:

  • public abstract void SUpdate(SocketWatched sw, XSocket sock)
    This method is called whenever data is received by the XSocket referred to in sock. This is the method you put data processing in. Note that you need to make calls to a read function (see above) to actually get the data.
  • public abstract void SSUpdate(SocketWatched sw, XServerSocket servsock, XSocket sock)
    This is used for server sockets. For programs only using client sockets, include this line in your class:
    public void SSUpdate(SocketWatched sw, XServerSocket servsock, XSocket sock){}

TCP/IP in an Applet

Java applets are subject to fairly stringent security measures – the so-called ‘sandbox’ – and among these is the fact that an applet can’t create TCP/IP sockets to arbitrary servers. However, they can connect back to the server they originated from; for example an online game might maintain a continuous connection to the server.

To do this using my sockets package, use the special constructor:
sock = new XSocket(self, 80); (for port 80), and to update the connection:
sock.updateConnection(self, 80);.

If you try to create a connection to an unauthorised source, a security exception may occur (depending on your browser).

Server Sockets

Of course, at some point you may want to write some sort of network or Internet server. Server sockets are implemented by the XServerSocket class. It has two constructors, XServerSocket() which starts a new server on port 80 (the default for HTTP/Web communications), and XServerSocket(int port) which starts one on the specified port.

Like the XSocket, XServerSocket contains a reference to a SocketWatched object called obs, which you have to add yourself to (with sock.obs.add(this) again). However, this time you want to implement SSUpdate. My usual is something along the lines of:
public void SSUpdate(SocketWatched xo, XServerSocket from, XSocket sock){
try{
... because writeString() can throw an exception if it fails
sock.writeString("Hello new socket no " + sock.getID());
}catch(java.io.IOException e){System.out.println("Couldn't write to socket " + sock.getID());}
sock.obs.add(this);
... add ourselves to the new socket’s SocketWatched
}

In the sock.obs.add(this) here, sock refers to the new XSocket produced by the XServerSocket when it receives a connection. We want to add ourselves to its SocketWatched object so we know when it receives data. You can see the call to XSocket.getID(): the XServerSocket allocates each new XSocket a unique ID when it creates it, so you can tell them apart with this. Of course, to make this useful you then have to implements SUpdate() as well so you can react to the XSocket.

Note that SSUpdate is called with an XSocket. This means that, while the XSocket class is usually created as a client socket, here it is effectively a “server XSocket”. However, in terms of functionality it is no different from any other XSocket (except that because the XServerSocket has set its ID, calls to setID() are fruitless); the class is entirely two-way and both ends can send, receive and close the connection with equal priority.

Do remember that a server application also needs to respond to specific requests using SUpdate(), just like the client example above. You probably also want to respond to the clients closing the connection (or the connection failing) to remove the client from some kind of table.

Download the classes

Here you can download the four classes. They should go into a sockets subfolder of your class folder.

A Plea For Attention

Is anyone actually using this stuff, or even reading down to here? Please mail me if you are!


Page and site © Richard Smith 2001
Please send any comments to richard@redcorona.com - thank you.
 Top   Home