Instead of explaining the functionality communication-oriented, I will describe each class in separation here. But we start with defining what a datagram is.
In the initialisation the applet determines its host:
String host = getCodeBase().getHost();
address = InetAddress.getByName(host);
(I have omitted the exception handling.)
The idea is here that the server runs on the same machine.
The applet will try later on to connect to that address.
Then, a datagram socket is created:
socket = new DatagramSocket();The next steps involve setting up the interface consisting of a label, a textfield (the port number the server is listening to has to be entered here) and a Send button (which sends the initial request to the server).
display = new Label("No number");
add(display);
portField = new TextField(6);
add(portField);
Button button = new Button("Send");
add(button);
validate();
validate makes sure that all GUI components are actually displayed
(this is not necessary for most of the existing browsers).
In case the Send button is pressed, the action method is invoked (this is an outdated construct, you can replace it by action listeners). Before the applet tries to connect to the server, the portnumber which should have been typed into the textfield is syntactially checked. In case the port number is an integer, the method proceeds and calls the connect-method:
public boolean action(Event event, Object arg) {
int port;
try {
port = Integer.parseInt(portField.getText());
} catch (NumberFormatException e) {
return true;
}
connect(port);
return true;
}
The connect-method creates an empty datagram packet first:
DatagramPacket packet;
byte[] sendBuf = new byte[256];
packet = new DatagramPacket(sendBuf, 256, address, port);
which is subsequently send to the server via the datagram socket
declared earlier on.
socket.send(packet);Then, a new packet is defined and the applet waits for the server to reply:
packet = new DatagramPacket(sendBuf, 256); socket.receive(packet);The server sends an integer value, which is converted into a string and displayed as a label:
String received = String.valueOf((int)(packet.getData())[0]);
display.setText(received);
class NetServer {
public static void main(String[] args) {
new NetServerThr().start();
}
}
NetServerThr() {
super("NetServer");
And it declares a datagram socket (as the applet):
private DatagramSocket socket = null; socket = new DatagramSocket();The it prints out to the screen at which port it is listening:
System.out.println("NetServer listening on port: " +
socket.getLocalPort());
This number has to be typed in into the textfield in the applet!
The run-method provides the implementation of the thread. It stops if an unvalid socket was created:
if (socket == null)
return;
In a loop, the thread will continuously wait for incoming
requests:
while (true) {
...
}
A packet is created in which incoming data is received:
packet = new DatagramPacket(buf, 256);
socket.receive(packet);
Address and port of the client are stored:
address = packet.getAddress();
port = packet.getPort();
The Server implements a counter. That means for each request from any client, it sends back an incremented number.
i = i + 1;The integer value is converted into a byte and stored as the first element of the buf-array. buf is the content of the datagram packet. The packet is send back to the client.
buf[0] = (byte)i;
packet = new DatagramPacket(buf, 1, address, port);
socket.send(packet);
At the end, when the server is shut down, the socket connection will be closed.
protected void finalize() {
if (socket != null) {
socket.close();
socket = null;
}
}
import java.applet.Applet;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class NetApplet extends Applet {
boolean DEBUG = true;
InetAddress address;
TextField portField;
Label display;
DatagramSocket socket;
public void init() {
String host = getCodeBase().getHost();
try {
address = InetAddress.getByName(host);
} catch (UnknownHostException e) {
System.out.println("Couldn't get Internet address: Unknown host");
}
try {
socket = new DatagramSocket();
} catch (SocketException e) {
System.out.println("Couldn't create new DatagramSocket");
return;
}
display = new Label("No number");
add(display);
portField = new TextField(6);
add(portField);
Button button = new Button("Send");
add(button);
validate();
}
void connect(int port) {
DatagramPacket packet;
byte[] sendBuf = new byte[256];
packet = new DatagramPacket(sendBuf, 256, address, port);
try { // send request
if (DEBUG) {
System.out.println("Applet about to send packet to address "
+ address + " at port " + port);
}
socket.send(packet);
if (DEBUG) {
System.out.println("Applet sent packet.");
}
} catch (IOException e) {
System.out.println("Applet socket.send failed:");
e.printStackTrace();
return;
}
packet = new DatagramPacket(sendBuf, 256);
try { // get response
if (DEBUG) {
System.out.println("Applet about to call socket.receive().");
}
socket.receive(packet);
if (DEBUG) {
System.out.println("Applet returned from socket.receive().");
}
} catch (IOException e) {
System.out.println("Applet socket.receive failed:");
e.printStackTrace();
return;
}
String received = String.valueOf((int)(packet.getData())[0]);
display.setText(received);
if (DEBUG) {
System.out.println("Result: " + received);
}
}
public boolean action(Event event, Object arg) {
int port;
try {
port = Integer.parseInt(portField.getText());
} catch (NumberFormatException e) {
//No integer entered. Should warn the user.
return true;
}
connect(port);
return true;
}
}
The server code is divided into a server program and the thread
code.
Here is the server program code:
class NetServer {
public static void main(String[] args) {
new NetServerThr().start();
}
}
And here is the server thread code:
import java.io.*;
import java.net.*;
import java.util.*;
class NetServerThr extends Thread {
private DatagramSocket socket = null;
NetServerThr() {
super("NetServer");
try {
socket = new DatagramSocket();
System.out.println("NetServer listening on port: " +
socket.getLocalPort());
} catch (java.net.SocketException e) {
System.err.println("Could not create datagram socket.");
}
}
public void run() {
int i = 0;
if (socket == null)
return;
while (true) {
try {
byte[] buf = new byte[256];
DatagramPacket packet;
InetAddress address;
int port;
String dString = null;
// receive request
packet = new DatagramPacket(buf, 256);
socket.receive(packet);
address = packet.getAddress();
port = packet.getPort();
// send response
i = i + 1;
buf[0] = (byte)i;
packet = new DatagramPacket(buf, 1, address, port);
socket.send(packet);
} catch (Exception e) {
System.err.println("Exception: " + e);
e.printStackTrace();
}
}
}
protected void finalize() {
if (socket != null) {
socket.close();
socket = null;
System.out.println("Closing datagram socket.");
}
}
}
© Claus Pahl