Cambios en el JDK 1.1:
El ejemplo KnockKnock

Tanto el ejemplo KnockKnockServer como KnockKnockClient utilizan un API que ha sido caducado en el JDK 1.1. Ambos programas utilizan el mismo API por lo que tiene sentido hablar de los dos a la vez.

Primero, tanto el cliente como el servidor utilizan el método DataInputStream.readLine que está caducado en el JDK 1.1 porque no convierte correctamente los bytes en caracteres. La mayoría de los programas que uitilizan DataInputStream.readLine pueden hacer un cambio sencillo para utilizar el mismo método de la nueva clase BufferedReader. Simplemente reemplaza el código de:

DataInputStream d = new DataInputStream(in);
con este:
BufferedReader d = new BufferedReader(new InputStreamReader(in));
En los dos programas se puede realizar este sencillo cambio.

Segundo, tanto el cliente como el servidor crean explícitamente un PrintStream para escribir en el Socket. Utilizar un PrintStream ha sido anulado en favor de PrintWriter.

Por eso, aquí tienes las nuevas versiones de los programas que corrigen esos problemas:

KnockKnockServer

import java.net.*;
import java.io.*;

class KnockKnockServer {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.out.println("Could not listen on port: " + 4444 + ", " + e);
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.out.println("Accept failed: " + 4444 + ", " + e);
            System.exit(1);
        }

        try {
            BufferedReader br = new BufferedReader(
                                 new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter pw = new PrintWriter(
                             new BufferedOutputStream(clientSocket.getOutputStream(), 1024), false);
            KKState kks = new KKState();
            String inputLine, outputLine;

            outputLine = kks.processInput(null);
            pw.println(outputLine);
            pw.flush();

            while ((inputLine = br.readLine()) != null) {
                 outputLine = kks.processInput(inputLine);
                 pw.println(outputLine);
                 pw.flush();
                 if (outputLine.equals("Bye."))
                    break;
            }
            pw.close();
            br.close();
            clientSocket.close();
            serverSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

KnockKnockClient

import java.io.*;
import java.net.*;

public class KnockKnockClient {
    public static void main(String[] args) {
        Socket kkSocket = null;
        PrintWriter pw = null;
        BufferedReader br = null;

        try {
            kkSocket = new Socket("taranis", 4444);
            pw = new PrintWriter(kkSocket.getOutputStream());
            br = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis");
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: taranis");
        }

        if (kkSocket != null && pw != null && br != null) {
            try {
                StringBuffer buf = new StringBuffer(50);
                int c;
                String fromServer;

                while ((fromServer = br.readLine()) != null) {
                    System.out.println("Server: " + fromServer);
                    if (fromServer.equals("Bye."))
                        break;
                    while ((c = System.in.read()) != '\n') {
                        buf.append((char)c);
                    }
                    System.out.println("Client: " + buf);
                    pw.println(buf.toString());
                    pw.flush();
                    buf.setLength(0);
                }

                pw.close();
                br.close();
                kkSocket.close();
            } catch (UnknownHostException e) {
                System.err.println("Trying to connect to unknown host: " + e);
            } catch (IOException e) {
                System.err.println("IOException:  " + e);
            }
        }
    }
}
KKMultiServerThread que implementa un servidor de chistes Knock Knock que soporta múltiples conexiones KnockKnockClient y utiliza exactamente el mismo API caducado y también debe ser modificado de forma similar. Aquí tienes la nueva versión del JDK 1.1 del KKMultiServerThread.java:
import java.net.*;
import java.io.*;

class KKMultiServerThread extends Thread {
    Socket socket = null;

    KKMultiServerThread(Socket socket) {
        super("KKMultiServerThread");
        this.socket = socket;
    }

    public void run() {
        try {
            BufferedReader br = new BufferedReader(
                                  new InputStreamReader(socket.getInputStream()));
            PrintWriter pw = new PrintWriter(
                              new BufferedOutputStream(socket.getOutputStream(), 1024), false);
            KKState kks = new KKState();
            String inputLine, outputLine;

            outputLine = kks.processInput(null);
            pw.println(outputLine);
            pw.flush();

            while ((inputLine = br.readLine()) != null) {
                outputLine = kks.processInput(inputLine);
                pw.println(outputLine);
                pw.flush();
                if (outputLine.equals("Bye"))
                    break;
            }
            pw.close();
            br.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


Ozito