-1

I am getting an Exception that I am unable to resolve.

package advanced.net;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class LottoClient {

    private InetAddress serverAddress;

    private int serverPort = LottoProtocol.SERVER_PORT;

    public static void main(String[] args) {
        System.out.println("Starting Client");
        LottoClient lottoClient1 = null;
        lottoClient1 = new LottoClient(); // This was not a TODO
        lottoClient1.startClient(args);
    }

    public LottoClient() {
    }

    private String getTicketFromServer() {
        String lotteryTicket = null;
        BufferedReader reader = null; // to get response from server
        PrintWriter writer = null; // to send request to server
        System.out.println("Getting Ticket");
        try {
            Socket socket = new Socket(serverAddress, serverPort);

            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();

            reader = new BufferedReader(new InputStreamReader(in));
            writer = new PrintWriter(out, true); // true for autoflush

            lotteryTicket = reader.readLine(); // read the response
        } catch (java.io.IOException e) {
            System.err.println("Error getting ticket");
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                if (writer != null) {
                    writer.close();
                }
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
        }

        // TODO 08. Return the lottery ticket String.
        return lotteryTicket;
    }

    /**
     * configData[0] is the name or IP address of the server
     */
    private void processConfigData(String configData[]) {
        try {
            // set address of server
            if (configData != null && configData.length >= 1) {
                serverAddress = InetAddress.getByName(configData[0]);
            } else {
                // default case is set in our protocol
                String host = LottoProtocol.SERVER_HOST;
                serverAddress = InetAddress.getByName(host);
            }
        } catch (java.net.UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public void startClient(String args[]) {
        processConfigData(args);
        String lottoTicket = getTicketFromServer();
        System.out.println(lottoTicket);
    }
}

package advanced.net;

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

public class LottoServer {

    // TODO 01. Make the handler a subclass of Thread.
    private class ClientRequestHandler extends Thread {

        private Socket socket = null;

        public ClientRequestHandler() {
            // Default Constructor
        }

        public ClientRequestHandler(Socket clientSocket) {
            socket = clientSocket;
        }

        /**
         * Generate a lotto ticket. Returns a formatted string containing 6
         * numbers from 1 to 49.
         */
        private String getTicket() {
            int theNumbers[] = new int[LottoProtocol.NUM_OF_NUMBERS];

            for (int i = 0; i < LottoProtocol.NUM_OF_NUMBERS; i++) {
                int newNumber;
                boolean isDuplicate = false;
                do {
                    isDuplicate = false; // reset isDuplicate, in case it has
                    // been set to true

                    // we want the numbers to be in the range of 1 to maxValue
                    // 0 to 48, and then add 1 to make it 1 to 49
                    newNumber = (int) (numberGenerator.nextDouble()
                            * (LottoProtocol.MAX_VALUE - 1) + 1);

                    // Compare to the numbers entered previously, to make sure
                    // it is
                    // not a duplicate.
                    // If it is, then ignore it, and get a new random number.
                    for (int j = 0; j < i && !isDuplicate; j++) {
                        if (newNumber == theNumbers[j]) {
                            isDuplicate = true;
                        }
                    }
                } while (isDuplicate);

                theNumbers[i] = newNumber;
            }
            Arrays.sort(theNumbers);
            StringBuffer sb = new StringBuffer();
            sb.append("Your numbers are: ");
            for (int k = 0; k < LottoProtocol.NUM_OF_NUMBERS; k++) {
                sb.append(String.valueOf(theNumbers[k]) + " ");
            }
            return sb.toString();
        }

        private void handleClientRequests() {
            BufferedReader reader = null; // to read client requests
            PrintWriter writer = null; // to send back response
            String request;

            try {
                InputStream in = socket.getInputStream();
                OutputStream out = socket.getOutputStream();

                reader = new BufferedReader(new InputStreamReader(in));
                writer = new PrintWriter(out, true); // true for autoflush

                writer.println("LottoServer 1.2");
                request = reader.readLine(); // read client request
                if (request
                        .equalsIgnoreCase(LottoProtocol.TICKET_REQUEST_COMMAND)) {
                    writer.println(getTicket()); // process the request
                }
            } catch (IOException ioe) {
                System.err.println("Error processing the request");
                ioe.printStackTrace();
            } finally {
                try {
                    if (reader != null) {
                        // TODO 05. Close the reader.
                        reader.close();
                    }
                    if (writer != null) {
                        // TODO 06. Close the writer.
                        writer.close();
                    }
                    if (socket != null) {
                        // TODO 07. Close the client socket.
                        socket.close();
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }

        public void run() {
            handleClientRequests();
        }

        public Socket getSocket() {
            return socket;
        }

        public void setSocket(Socket socket) {
            this.socket = socket;
        }
    }

    public static void main(String[] args) {
        LottoServer lottoServer1 = new LottoServer();
        lottoServer1.startServer();
    }

    private Random numberGenerator = new Random(System.currentTimeMillis());

    private ServerSocket serverSocket = null;

    public LottoServer() {
    }

    private void acceptConnections() {
        Socket clientSocket;
        while (true) {
            try {
                // TODO 02. Get the socket from the client.
                System.out.println("Socket Empty");
                clientSocket = null;
                clientSocket = serverSocket.accept();
                System.out.println("Socket Captured");
                // TODO 03. Create a new instance of the handler.
                ClientRequestHandler handler = null;
                handler = new ClientRequestHandler();
                System.out.println("Handler Created");
                handler.setSocket(clientSocket);
                Thread thread = new Thread(handler);
                System.out.println("Thread Created");
                // TODO 04. Start the new thread.
                thread.start();
                System.out.println("Thread Started Created");
            } catch (java.io.IOException e) {
                System.err.println("Error setting up connection");
                e.printStackTrace();
            }
        }
    }

    private void createServerSocket() {
        try {
            serverSocket = new ServerSocket(LottoProtocol.SERVER_PORT);
            System.out.println("Socket Created");
        } catch (java.io.IOException e) {
            String error = "Error setting up connection" + e.getMessage();
            System.err.println(error);
        }
    }

    public void startServer() {
        System.out.println("Server Started");
        createServerSocket();
        acceptConnections();
    }

}

package advanced.net;

public class LottoProtocol {

    public static final int MAX_VALUE = 49;

    public static final int NUM_OF_NUMBERS = 6;

    public static final String SERVER_HOST = "localhost";

    public static final int SERVER_PORT = 5123;

    public static final String TICKET_REQUEST_COMMAND = "GetTicket";
}

I've written println statements to check crucial points in the code. I believe it is where I am telling the thread to start after a client has connected but I cannot follow where the null pointer is from.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
ChunWu
  • 13
  • 5
  • 3
    What is the stacktrace of the exception? – J Fabian Meier Jun 21 '16 at 19:21
  • 1
    What type of Exception? – Compass Jun 21 '16 at 19:22
  • 1
    `I cannot follow where the null pointer is from` May you [edit](http://stackoverflow.com/posts/37952889/edit) your question to include the stack trace of that `NullPointerException`? – The SE I loved is dead Jun 21 '16 at 19:23
  • Pardon my ignorance... how do I use stacktrace/export it so I can attach? – ChunWu Jun 22 '16 at 17:56
  • Answering my stupidity: http://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors – ChunWu Jun 22 '16 at 18:05
  • Exception in thread "Thread-1" java.lang.NullPointerException at advanced.net.LottoServer$ClientRequestHandler.handleClientRequests(LottoServer.java:85) at advanced.net.LottoServer$ClientRequestHandler.run(LottoServer.java:112) at java.lang.Thread.run(Thread.java:745) – ChunWu Jun 22 '16 at 18:06

1 Answers1

0

It would be helpful if you attached the stacktrace of the exception you've mentioned. But leaving that aside, your problem lies (probably - again, no stack trace) in the handleClientRequests() method of the ClientRequestHandler class, specifically in the following line:

request = reader.readLine(); // read client request

From BufferedReader JavaDocs, readline() returns:

A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached.

So, if your server receives an empty message, the first invocation to readline() will return null, and in the next line:

if (request.equalsIgnoreCase(LottoProtocol.TICKET_REQUEST_COMMAND)) {

you're going to get a NullPointerException. As an easy fix, you can reverse this equality check and use:

if (LottoProtocol.TICKET_REQUEST_COMMAND.equalsIgnoreCase(request)) {
korolar
  • 1,340
  • 1
  • 11
  • 20
  • That solved the issue with the exception but I am not intending that the first call should have a NULL pointer. Once I made the change based on your recommendations I get no exceptions but I am also not getting numbers returned. – ChunWu Jun 22 '16 at 18:10
  • Problem Solved! Had one line of misplaced code. Thank-you so much! – ChunWu Jun 22 '16 at 18:22