How To: Using Sockets with JBuilder 2

Posted: (EET/GMT+2)

 

How To: Using Sockets with JBuilder 2

Level: JBuilder 2 Intermediate


Applications need connections. In Java, TCP connections can be created by using the Socket class. In this How To you will learn how to create a very simple "telnet" style application, which lets you test the workings of a mail server, for instance.


Using Sockets

The Socket class, found in the java.io package, is used to create TCP connections. The sample application has two text areas, one for input text and one for output text. To let the user specify which server and port to connect the UI also has two simple textfields.

To connect to the user specified server, the following code gets executed:

    void btnConnect_actionPerformed(ActionEvent e) {
      try {
        demoSocket = new Socket(tfHostName.getText(),
           new Integer(tfPortNumber.getText()).intValue());
        timerClient = new MyTimerClient();
        Timer.startTimer(timerClient,1,1000,true);
        readInput();
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    
Here, the code making the connection simply the constructor call for the Socket class. Also, because the Socket class is quite bare, it can't fire an event when data arrives to read. For this reason we're using the Timer class. Our timer will fire once a second, and check whether data has arrived to the socket (this data is called "output").

The Timer class needs an implementation of the TimerClient interface. It looks like this (note that this is an "inner class"):

    public class MyTimerClient implements TimerClient{
      public int x = 0;
    
      public void timerEvent(int id) {
        readInput();
        x++;
        setTitle("Socket Demonstration - "+new Integer(x).toString());
      }
    }
    
Don't worry about the title text. The variable x is simply used to make sure that data gets read from the Socket. So it is simply a debugging aid.

Reading from and writing to a Socket

To read from a Socket, we need to get access to the "input stream". This is like an ordinary stream, with methods like read() to get the data. Note that the read method used in the demo application is blocking in a way that if no data is available, the method waits until some data is. The code for reading is:

    void readInput() {
      int i;
      InputStream is;
      String reply = new String();
    
      try {
        is = demoSocket.getInputStream();
        while (is.available() != 0) {
          i = is.read();
          char[] readChar = {(char)i};
          reply += new String(readChar);
        }
        if (reply.compareTo("") != 0) {    // we actually did read something
          taInput.setText(taInput.getText()+reply);
        }
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    
Here, a String is filled with the characters read from the stream. If we found something to read, then the resulting text is appended to the taInput textarea.

To write data, we need an OutputStream. This stream is used when an user presses a key in the input area. The actual writing is handled by the OutputStream.write() method. Note that if the user presses Enter (ASCII #13), a newline character (ASCII #10) is also sent. This makes it easy to play for example with SMTP, POP3, HTTP and FTP servers. Code follows:

    void taOutput_keyTyped(KeyEvent e) {
      int i;
      OutputStream os;
      char charToSend = e.getKeyChar();
    
      try {
        os = demoSocket.getOutputStream();
        os.write((int)charToSend);
        if (charToSend == '\r') {
          os.write('\n'); // newline to form a CRLF pair
        }
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    

Conclusion

Using Socket is quite easy with Java. Using Timers requires some more from the coder, but by means nothing supernatural. Still, JBuilder should have a visual component to present a Timer.