线程中的异常

时间:2012-02-29 18:44:40

标签: java multithreading io

以下错误是通过删除声明来修复的,但另一个已经出现以前不存在。

收到两个错误,任何见解都会很棒,谢谢。

  

线程“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 个答案:

答案 0 :(得分:3)

是的,就是这一行:

line = console.readLine();

console仍然为空。即使你正在调用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
}

答案 1 :(得分:1)

对于第一个例外,永远不会为console分配一个对象,因此您无法在其上调用方法:

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

同样,对于第二个例外,

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

问题在于重新陈述start()中变量的类型。这实际上创建了 new 变量,这些变量仅对该方法是本地的,并且不引用同名的全局变量。

答案 2 :(得分: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());
   }

答案 3 :(得分: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()方法中犯了同样的错误

答案 4 :(得分: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());
}