Исключение в потоке - PullRequest
       6

Исключение в потоке

1 голос
/ 29 февраля 2012

Приведенная ниже ошибка исправлена ​​удалением объявления, но появилось другое, которого раньше не было.

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

Исключение в потоке "main" java.lang.NullPointerException в ChatClient. (ChatClient.java:27) в 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();
   }
}

Ответы [ 5 ]

3 голосов
/ 29 февраля 2012

Да, это такая строка:

line = console.readLine();

console по-прежнему равно нулю. Даже если вы звоните start(), он не делает то, что вы думаете:

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

Здесь объявляется новая локальная переменная с именем console. Это не меняет значение переменной instance с именем console. Для этого необходимо удалить часть объявления:

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

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

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

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

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

if (foo) {
     // Do something
}

или

if (foo)
{
     // Do something
}
1 голос
/ 29 февраля 2012

Это потому, что консоль пуста.Чтобы устранить проблему, измените ваш метод 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());
}
1 голос
/ 29 февраля 2012

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

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 голос
/ 29 февраля 2012

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

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 голос
/ 29 февраля 2012

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...