Helping ordinary people create extraordinary websites!
HOME TUTORIALS SCRIPTS WEB HOSTING BLOG FORUM
Get Our Newsletter
Email:

Understanding Sockets in Unix, NT, and Java

By Ken Nordby
2003-05-26


Client program (Java)

The Java client program is functionally equivalent to the C++ client. Its purpose is to illustrate the availability of sockets technology on the Java platform. The Java client presents a graphical user interface comprising two windows, although the client is still text-based because of the nature of the application. The first window prompts for a Unix command string, and the second window presents the resulting man page information.

Environment
The Java client program was developed on Windows NT 4.0 with IBM VisualAge for Java 1.0 and is executed within the VisualAge environment as a graphical application.

Imported Packages

  • java.net
    Provides classes for network programming
  • java.io
    Provides input/output classes
  • java.awt
    Provides classes for graphical user interface.

The Java client consists of two classes, ManPage and ManPageWindow. The ManPage class starts the application by instantiating itself in main(), and the ManPage constructor then instantiates a ManPageWindow object and initializes it as a main window. When the user enters a command string into the main window, the client instantiates another ManPageWindow object and initializes it as an output window.

Creating a Socket
Unlike the C++ client program and the server program, the Java client does not use the standard socket() call to create a socket descriptor. The Java language provides support for sockets through two socket classes which encapsulate the standard sockets functionality. This illustrates the similarity between the Java implementation of sockets and the Unix implementation. Again, the basic concepts of sockets communication are applicable across platforms.

The java.net.Socket class provides functionality for a client-side socket. The corresponding class java.net.ServerSocket provides functionality for a server-side socket. When you instantiate a client Socket object, you specify the name of the remote host machine and the port number to which you wish the socket to be connected. The constructor creates the socket and also attempts to connect it to the requested host, simplifying the job of the application developer. In the sample program, the server hostname is specified as bookworld. The full Domain Name System name for this machine is bookworld.raleigh.ibm.com. Following the Unix approach in which sockets are treated conceptually and syntactically almost as if they were files, the Java Socket class provides getInputStream() and getOutputStream() methods to support reading and writing data through a socket. What about the three arguments required for the socket() call-- AF_INET, SOCK_STREAM, and 0? It is not necessary to specify these arguments when instantiating a socket object in Java. Since these are the most common values, they are provided as defaults.

Connecting to the Server
When a ManPageWindow object is initialized as a main window, it not only instantiates window components such as TextField, Panel, and Button, but it also invokes socket methods to establish connectivity with the server. A Socket object, socket1, is created with the new operator. The constructor method implicitly issues the equivalent of a connect() call, specifying the server host name bookworld and the port number, 10001. Unless an error is encountered, the Socket constructor returns a Socket object already connected to the server process on the target machine.

Next the initialize routine, initMainWIndow(), creates stream objects associated with the connected socket. dataInputStream1 and dataOutputStream1 are conceptually like traditional files and take advantage of the fact that sockets were designed to function much like files. These stream objects provide read and write methods which the Java client later uses to transfer data through socket1.

Exchanging Data with the Server
When a text string is entered into the TextField object in the main window, the action() method invokes processRequest(). This method writes the input string to the socket by way of the output stream object, appending hex ff. The input string data from the Java client arrives in the server program over the sd2 socket and the server program generates appropriate man page output. The Java client receives response data from the server through the input stream object associated with socket1. Note that by routing socket data movement through stream objects the Java environment effectively encapsulates the standard sockets functionality. This simplifies the work of the developer since the input/output idiosyncrasies of sockets are hidden behind the standard input/output functionality of the Java stream objects.

After the Java client transmits a request string to the server, the processRequest() method begins a read loop on the socket using the readUnsignedByte() method. It is necessary to read the input data stream in this primitive manner, one byte at a time, because the Java environment represents text in two-byte Unicode characters, and the data stream transmitted from the server is not encoded in Unicode. readUnsignedByte() returns the input data as an integer, which is tested for hex ff, and then is cast to a Unicode character. If the character is not a newline, formfeed, or carriage return it is stored in the input array; otherwise the input array is passed to printOutput() as a String object and appended to the output text in the output window.

Code for client program (Java)



<xmp>
//Client Program - Java
import java.net.*;
import java.io.*;
import java.awt.*;

class ManPage
{
public ManPage( )
{
ManPageWindow mainWindow=new ManPageWindow("Help for Unix Commands");
mainWindow.initMainWindow();
ManPageWindow.windowCounter++;
return;
} //end constructor

public static void main(String&lbracket.&rbracket. args)
{
ManPage myManPage=new ManPage();
} //end main()
} //end class

class ManPageWindow extends java.awt.Frame
{
ManPageWindow mainWindow,outputWindow;
static int windowCounter=0;
static String spaceString=new String(" ");
Panel panel1,panel2;
Button button1;
TextField textField1;
List list1;
String string1;
Socket socket1;
InputStream inputStream1;
OutputStream outputStream1;
DataOutputStream dataOutputStream1;
DataInputStream dataInputStream1;
int inputInt,charCounter,lastChar;
char inputChar,inputChars&lbracket.&rbracket.=new char&lbracket.256&rbracket.;

public ManPageWindow(String title)
{
super(title);
button1=new Button("Exit");
} //end constructor

public boolean action(Event e, Object o)
{
if (e.target==textField1)
{
string1=textField1.getText();
if (string1.indexOf("bye")>=0)
{
System.exit(0);
return true;
}
processRequest();
textField1.setText(spaceString);
textField1.setText(new String(""));
return true;
}
else
{
System.exit(0);
return true;
}
} //end action()

public void initMainWindow()
{
textField1=new TextField(25);
setBackground(Color.green);
setLayout(new GridLayout(2,1));
panel1=new Panel();
panel2=new Panel();
textField1.setBackground(Color.white);
panel1.add(textField1);
panel2.add(button1);
panel1.setBackground(Color.green);
panel2.setBackground(Color.green);
add(panel1);
add(panel2);
resize(300,100);
show();
textField1.requestFocus();
try {
socket1=new Socket("bookworld",10001);
}
catch (UnknownHostException e) {System.err.println(e);System.exit(0);}
catch (IOException e) {System.err.println(e);System.exit(0);}
//socket is now connected
try {
outputStream1=socket1.getOutputStream();
}
catch (IOException e) {System.err.println(e);System.exit(0);}
dataOutputStream1=new DataOutputStream(outputStream1);
try {
inputStream1=socket1.getInputStream();
}
catch (IOException e) {System.err.println(e);System.exit(0);}
dataInputStream1=new DataInputStream(inputStream1);
// we now have input and output streams for the socket
return;
}//end initMainWindow()

public void initOutputWindow()
{
setBackground(Color.cyan);
list1=new List(200);
add(list1);
resize(500,250);
move(100,175);
show();
return;
} //end initOutputWindow()

public void printOutput(String s)
{
list1.addItem(s);
show();
return;
} //end printOutput()

public void processRequest()
{
if (windowCounter>1)
{
outputWindow.hide();
outputWindow.dispose();
windowCounter--;
}
outputWindow=new ManPageWindow("Manpage");
outputWindow.initOutputWindow();
windowCounter++;
try
{
dataOutputStream1.writeBytes(string1);
dataOutputStream1.writeByte(0xff);
}
catch (IOException e) {System.err.println(e);System.exit(0);}
for (charCounter=0;charCounter<=lastChar;charCounter++);
inputChars&lbracket.charCounter&rbracket.='\0';
charCounter=0;
inputInt=0x00000001;
while(inputInt!=0x000000ff)
{
try
{
inputInt=dataInputStream1.readUnsignedByte();
}
catch (IOException e) {System.out.println(e);System.exit(0);}
if (inputInt!=0x000000ff)
{
inputChar=(char) inputInt;
if (inputChar!='\n' && inputChar!='\f' && inputChar!='\r')
{
inputChars&lbracket.charCounter++&rbracket.=inputChar;
if (inputChars&lbracket.charCounter-1&rbracket.=='\t')
{
inputChars&lbracket.charCounter-1&rbracket.=' ';
inputChars&lbracket.charCounter++&rbracket.=' ';
inputChars&lbracket.charCounter++&rbracket.=' ';
}
}
else
{
lastChar=charCounter;
try
{
outputWindow.printOutput(new String(inputChars,0,lastChar));
}
catch (StringIndexOutOfBoundsException e)
{System.out.println(e);System.exit(0);}
for (charCounter=0;charCounter<=lastChar;charCounter++);
inputChars&lbracket.charCounter&rbracket.='\0';
charCounter=0;
}
}
else
{
lastChar=charCounter;
try
{
outputWindow.printOutput(new String(inputChars,0,lastChar));
}
catch (StringIndexOutOfBoundsException e)
{System.out.println(e);System.exit(0);}
}
} //end while
return;
} //end processRequest()
} //end class
</xmp>

To cut and paste this code, click here.



Tutorial Pages:
» Understanding Sockets in Unix, NT, and Java
» Basic sockets concepts
» A simple example
» Sample sockets application
» Server program (Unix)
» Client program (NT)
» Client program (Java)
» Further study


First published by IBM DeveloperWorks


 | Bookmark
Related Tutorials:
» All about JAXP, Part 1
» Make Database Queries Without the Database
» Load List Values for Improved Efficiency
» 2 Ways To Implement Session Tracking
» A Simple Way to Read an XML File in Java
» Develop Aspect-Oriented Java Applications with Eclipse and AJDT