2012-02-29 2 views
1

Ошибка ниже фиксируется удалением декларации, но другая появилась, которая ранее не существовала.Исключение в потоке

Получение двух ошибок, любое понимание было бы замечательным, спасибо.

Exception in thread "main" java.lang.NullPointerException at ChatClient.(ChatClient.java:27) at ChatClient.main(ChatClient.java:59)

Со следующего ChatClient:

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

public class ChatClient 
{ private Socket socket    = null; 
    private BufferedReader console = null; 
    private BufferedReader streamIn = null; 
    private DataOutputStream streamOut = null; 

    public ChatClient(String serverName, int serverPort, String userName) 
    { System.out.println("Establishing connection. Please wait..."); 
     try 
     { socket = new Socket(serverName, serverPort); 
     System.out.println("Connected: " + socket); 
     System.out.println("CTRL+C or type .bye to quit"); 
     start(); 
     } 
     catch(UnknownHostException uhe) 
     { System.out.println("Host unknown: " + uhe.getMessage()); 
     } 
     catch(IOException ioe) 
     { System.out.println("Unexpected exception: " + ioe.getMessage()); 
     } 
     String line = ""; 
     while (!line.equals(".bye")) 
     { try 
     { line = console.readLine(); 
      streamOut.writeBytes(line + '\n'); //Send console data to server socket 
      String reply = streamIn.readLine(); //Recieve confirmation msg from server 
      System.out.println(reply); //Print the msg 
      streamOut.flush(); 
     } 
     catch(IOException ioe) 
     { System.out.println("Sending error: " + ioe.getMessage()); 
     } 
     } 
    } 
    public void start() throws IOException 
    { console = new BufferedReader(new InputStreamReader(System.in)); //Changed console to BufferedReader 
     streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     streamOut = new DataOutputStream(socket.getOutputStream()); 
    } 
    public void stop() 
    { try 
     { if (console != null) console.close(); 
     if (streamOut != null) streamOut.close(); 
     if (streamIn != null) streamIn.close(); //Is it good practice to close 
     if (socket != null) socket.close(); 
     } 
     catch(IOException ioe) 
     { System.out.println("Error closing ..."); 
     } 
    } 
    public static void main(String args[]) 
    { ChatClient client = null; 
     if (args.length != 3) 
     System.out.println("Usage: java ChatClient host port username"); 
     else 
     client = new ChatClient(args[0], Integer.parseInt(args[1]), args[2]); 
    } 
} 

и эта ошибка:

Exception in thread "Thread-1" java.lang.NullPointerException 
     at ChatServerThread.handleClient(ChatServerThread.java:41) 
     at ChatServerThread.run(ChatServerThread.java:17) 

из ChatServerThread:

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

//public class ChatServerThread implements Runnable 
public class ChatServerThread extends Thread 
{ private Socket   socket = null; 
    private ChatServer  server = null; 
    private int    ID  = -1; 
    private BufferedReader streamIn = null; 
    private DataOutputStream streamOut = null; 

    public ChatServerThread(ChatServer _server, Socket _socket) 
    { server = _server; socket = _socket; ID = socket.getPort(); 
    } 
    public void run() { 
    try { 
     handleClient(); 
    } catch(EOFException eof) { 
     System.out.println("Client closed the connection."); 
    } catch(IOException ioe) { 
     ioe.printStackTrace(); 
    } 
} 

    public void handleClient() throws IOException { 
     boolean done = false; 
     try { 
     System.out.println("Server Thread " + ID + " running."); 
     while (!done) { 
     String nextCommand = streamIn.readLine(); 
     if(nextCommand.equals(".bye")) { 
      System.out.println("Client disconnected with bye."); 
      done = true; 
     } else { 
      System.out.println(nextCommand); 
      String nextReply = "You sent me: " + nextCommand.toUpperCase() + '\n'; 
      streamOut.writeBytes (nextReply); 
     } 
    } 
    } finally { 
    streamIn.close(); 
    streamOut.close(); 
    socket.close(); 
    } 
    } 
    public void open() throws IOException 
    { 
     streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     streamOut = new DataOutputStream(socket.getOutputStream()); 
    } 
    public void close() throws IOException 
    { if (socket != null) socket.close(); 
     if (streamIn != null) streamIn.close(); 
     if (streamOut != null) streamOut.close(); 
    } 
} 
+0

Просьба указать в коде, какие именно строки вызывают эти ошибки. – talnicolas

+0

Какие строки в ваших образцах соответствует NPE. Что-то в этой строке должно быть нулевым. Может быть, вы не вызывали start() где-то? – Gray

+0

Обновленный ответ от обратной связи ниже, но появился другой вопрос с потоком. – Astron

ответ

3

Да, эта линия:

line = console.readLine(); 

console - еще null. Несмотря на то, что вы звоните start(), он не делает то, что вы думаете, он делает:

public void start() throws IOException 
{ BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); 

Это объявляет новую переменную местного под названием console. Он не изменяет значение аргумента с именем console. Чтобы сделать это, вы должны удалить объявление часть:

public void start() throws IOException 
{ 
    console = new BufferedReader(new InputStreamReader(System.in)); 
    ... 

Даже с этим изменением, вы можете получить проблемы - потому что если делает сгенерирует исключение, вот что вы делаете с ним в конструкторе:

catch(IOException ioe) 
{ System.out.println("Unexpected exception: " + ioe.getMessage()); 
} 

Вы продолжаете, как будто ничего не случилось. Не делай этого. Вы действительно не «обрабатываете» исключение, поэтому почти наверняка или не поймаете его в первую очередь, или не свернете в свой блок catch.

Как и в стороне, ваш стиль крепления очень плотный, очень нетрадиционный и непоследовательный. Я бы решительно не рекомендуем указывать код, соответствующий открывающей рамке (на этой же строке). Как это, ваш код очень трудно читать для тех, кто используется либо из (значительно) более общих соглашений о:

if (foo) { 
    // Do something 
} 

или

if (foo) 
{ 
    // Do something 
} 
+0

Это были заявления, которые я недавно добавил. – Astron

1

Для первого исключения console никогда назначен объект, так что вы не можете вызвать метод на нем:

line = console.readLine(); 
//   ^still null 

Аналогично для второго исключения,

streamIn.close(); 
// ^streamIn is still null 

Проблема заключается в повторной постановке типов переменных в start(). Это фактически создает переменные , которые являются локальными только для этого метода и не относятся к глобальным одноимённым именам.

+0

Что делать с 'streamIn.close();', это может быть связано со второй ошибкой, которую я получаю при закрытии клиента с помощью CTRL-C – Astron

+0

@ Астрон просто пишет 'streamIn = new BufferedReader ...' вместо «BufferedReader streamIn = new BufferedReader ...», как это было предложено всеми. – paislee

+0

Gotcha, не знал, выдумываете что-то другое. – Astron

1

Теперь он должен работать для клиента

public void start() throws IOException 
    { console = new BufferedReader(new InputStreamReader(System.in)); //Changed console to BufferedReader 
     streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     streamOut = new DataOutputStream(socket.getOutputStream()); 
    } 
1

В вашем методе запуска

public void start() throws IOException 
{ BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); //Changed console to BufferedReader 
    BufferedReader streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    DataOutputStream streamOut = new DataOutputStream(socket.getOutputStream()); 

}

Вы объявляете новые местные переменные, а не, как я думаю, что вы хотели, выделяя переменные экземпляра, которые вы уже объявили. Если вы измените его на

public void start() throws IOException 
{ console = new BufferedReader(new InputStreamReader(System.in)); //Changed console to BufferedReader 
    streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    streamOut = new DataOutputStream(socket.getOutputStream()); 
} 

Он должен работать

Вы делаете ту же ошибку в open() методы Вашего второго класса

1

Это потому, что консоль является недействительной. Чтобы устранить эту проблему, измените свой метод start(); как:

public void start() throws IOException 
{ 
    console = new BufferedReader(new InputStreamReader(System.in)); 
    streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    streamOut = new DataOutputStream(socket.getOutputStream()); 
} 
Смежные вопросы