2016-06-21 6 views
-1

Ich bekomme eine Ausnahme, die ich nicht lösen kann.Ausnahme im Thread - Multi-Threaded Lotto Programm

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"; 
} 

Ich habe println Anweisungen geschrieben, um entscheidende Punkte im Code zu überprüfen. Ich glaube, dass es ist, wo ich den Thread sage, um zu beginnen, nachdem ein Klient verbunden ist, aber ich kann nicht folgen, wo der Nullzeiger von ist.

+3

Was ist der Stacktrace der Ausnahme? –

+1

Welche Art von Ausnahme? – Compass

+1

'Ich kann nicht folgen, woher der Null-Zeiger stammt. Können Sie [edit] (http://stackoverflow.com/posts/37952889/edit) Ihre Frage nach dem Stack-Trace dieser' NullPointerException'? – dorukayhan

Antwort

0

Es wäre hilfreich, wenn Sie den Stacktrace der Ausnahme, die Sie erwähnt haben, angefügt haben. Aber verlassen, dass abgesehen, Ihr Problem liegt (wahrscheinlich - auch hier kein Stack-Trace) in der handleClientRequests() Methode der ClientRequestHandler Klasse, und zwar in der folgenden Zeile:

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

Von BufferedReader JavaDocs, readline() kehrt:

Ein String, der den Inhalt der Zeile enthält, ohne Zeichen für die Zeilenendung, oder null, wenn das Ende des Streams erreicht wurde.

Also, wenn Ihr Server eine leere Nachricht empfängt, wird der erste Aufruf zu readline() null zurück, und in der nächsten Zeile:

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

Sie gehen ein NullPointerException zu bekommen. Als einfache Lösung können Sie diese Überprüfung aufheben und verwenden:

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

Das löste das Problem mit der Ausnahme, aber ich habe nicht vor, dass der erste Aufruf einen Nullzeiger haben sollte. Sobald ich die Änderung basierend auf Ihren Empfehlungen vorgenommen habe, bekomme ich keine Ausnahmen, aber ich bekomme auch keine Zahlen zurück. – user3625654

+0

Problem gelöst! Hatte eine Zeile falsch platzierten Code. Ich danke dir sehr! – user3625654

Verwandte Themen