Como muchos otros programas que has visto en esta sección, QuoteServerThread utiliza el método DataInputStream.readLine que ha caducado en el JDK 1.1 porque no convierte correctamente los bytes en caracteres. La mayoría de los programas que utilizan DataInputStream.readLine pueden hacer un sencillo cambio para utilizar el mismo método de la nueva clase BufferedReader. Simplemente reemplaza este código:
por éste:DataInputStream d = new DataInputStream(in);
QuoteServerThread es uno de estos programas en los que se puede hacer el cambio.BufferedReader d = new BufferedReader(new InputStreamReader(in));
QuoteServerThread utiliza el métocado caducado getBytes de la clase String y QuoteClient utiliza un constructor caducado de StingString(byte[], int). Ambos métodos convierten incorrectamente los bytes en caracteres. Los programadores deberán ahora utilizar el correspondiente método o constructor que utilice codificación de caracteres.
El ejemplo QuoteServerThread utiliza el nuevo método getBytes que utiliza la codificación de caracteres por defecto y devuelve un array de bytes:byte[] getBytes().
import java.io.*;
import java.net.*;
import java.util.*;
class QuoteServerThread extends Thread {
private DatagramSocket socket = null;
private BufferedReader qfs = null;
QuoteServerThread() {
super("QuoteServer");
try {
socket = new DatagramSocket();
System.out.println("QuoteServer listening on port: " + socket.getLocalPort());
} catch (java.io.IOException e) {
System.err.println("Could not create datagram socket.");
}
this.openInputFile();
}
public void run() {
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
if (qfs == null)
dString = new Date().toString();
else
dString = getNextQuote();
buf = dString.getBytes();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
} catch (IOException e) {
System.err.println("IOException: " + e);
e.printStackTrace();
}
}
}
protected void finalize() {
if (socket != null) {
socket.close();
socket = null;
System.out.println("Closing datagram socket.");
}
}
private void openInputFile() {
try {
qfs = new BufferedReader(new InputStreamReader(new FileInputStream("one-liners.txt")));
} catch (java.io.FileNotFoundException e) {
System.err.println("Could not open quote file. Serving time instead.");
}
}
private String getNextQuote() {
String returnValue = null;
try {
if ((returnValue = qfs.readLine()) == null) {
qfs.close();
this.openInputFile();
returnValue = qfs.readLine(); // we know the file has at least one input line!
}
} catch (IOException e) {
returnValue = "IOException occurred in server.";
}
return returnValue;
}
}
La nueva versión de QuoteClient utiliza el constructor de String que toma un array de bytes y utiliza la codificación de caracteres por defecto: String(byte[]).
import java.io.*;
import java.net.*;
import java.util.*;
class QuoteClient {
public static void main(String[] args) {
int port;
InetAddress address;
DatagramSocket socket = null;
DatagramPacket packet;
byte[] sendBuf = new byte[256];
if (args.length != 2) {
System.out.println("Usage: java QuoteClient <hostname> <port#>");
return;
}
try {
// bind to the socket
socket = new DatagramSocket();
} catch (java.io.IOException e) {
System.err.println("Could not create datagram socket.");
}
if (socket != null) {
try {
// send request
port = Integer.parseInt(args[1]);
address = InetAddress.getByName(args[0]);
packet = new DatagramPacket(sendBuf, 256, address, port);
socket.send(packet);
// get response
packet = new DatagramPacket(sendBuf, 256);
socket.receive(packet);
String received = new String(packet.getData());
System.out.println("Quote of the Moment: " + received);
socket.close();
} catch (IOException e) {
System.err.println("IOException: " + e);
e.printStackTrace();
}
}
}
}