NullPoInterException试图连接到LocalHost服务器



标题可能并不十分清楚,我不确定我应该如何用问题,但简而言之,我试图在Java中创建一个"聊天"程序。我使用2个不同的文件聊天服务器和聊天夹。

程序的工作原理是您首先打开ChatServer,然后打开ChatClient,以连接到ChatServer。要连接您首先需要在第一个Textfield中编写用户名,然后按Enter。然后该程序试图将您连接到服务器,这是问题开始的地方。

每当我尝试连接到服务器时,我都会得到NullPoInterException,我不明白为什么。我已经尝试了很长时间来理解,但是我看不到错误。

该程序的重点是mutliple chatclients可以连接到聊天服务器(最多5个人(并互相写入。我知道这个问题非常具体,我希望是否有人能将我指向正确的方向,我会很高兴!

chatserver

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
public class ChatServer extends Application 
{
    private ArrayList<ObjectOutputStream> outputToUsers;
    private TextArea taServer = new TextArea();
    private static final int MAX_USERS = 5;
    private boolean acceptingNewUsers = true;
    private int connectedUsers = 0;
    private static final int port = 4999;
    public static void main(String[] args) 
    {
        launch(args);
    }
    @Override  
    public void start(Stage primaryStage) 
    { 
        initializePrmaryStage(primaryStage);
        new Thread( () -> 
        { 
          try 
          { 
            // Create a server socket 
            @SuppressWarnings("resource")
            ServerSocket serverSocket = new ServerSocket(port);
            Platform.runLater(() -> taServer.appendText(new Date() + ": Server started at socket: " + port + 'n'));  
            acceptUsers();
            while (true) 
            { 
                if (acceptingNewUsers)
                {
                     // Listen for a new connection request 
                    Socket socket = serverSocket.accept();
                    connectedUsers++;
                    if (connectedUsers == MAX_USERS)
                        refuseNewUsers();
                  // Create and start a new thread for the connection 
                  new Thread(new AddUserToChat(socket)).start(); 
                }
            } 
          } 
          catch(IOException ex) 
          { 
            System.err.println(ex); 
          } 
        }).start(); 
     } 
    private void initializePrmaryStage(Stage stage)
    {
        taServer.setMinHeight(450);
         // Create a scene and place it in the stage 
        Scene scene = new Scene(new ScrollPane(taServer), 450, 400); 
        stage.setTitle("ChatServer"); // Set the stage title 
        stage.setScene(scene); // Place the scene in the stage 
        stage.show(); // Display the stage 
    }
    private void acceptUsers()
    {
        acceptingNewUsers = true;
        Platform.runLater(() -> taServer.appendText(new Date() + ": " + "Accepting users" + 'n'));
    }
    private void refuseNewUsers()
    {
        acceptingNewUsers = false;
        Platform.runLater(() -> taServer.appendText("Maximum user capacity reached." + 'n'));
    }
    private void writeToAll(String s)
    {
        try 
        {
            for (int x = 0; x < outputToUsers.size(); x++)
            {
                outputToUsers.get(x).writeObject(s);
                outputToUsers.get(x).flush();
            }
        } catch (IOException ex) 
        {
            ex.printStackTrace();
        } 
    }
    private void writeToLog(String s)
    {
        Platform.runLater(() -> 
        { 
            taServer.appendText(s); 
        }); 
    }
    private class AddUserToChat implements Runnable 
    {
         private ObjectInputStream fromUser;
         private ObjectOutputStream toUser;
         private String username;
         private Socket userSocket;
        @SuppressWarnings("unused")
        public AddUserToChat(Socket userSocket) 
         {
             this.userSocket = userSocket;
             connectedUsers++;
         }
        @Override
        public void run() 
        {
             try 
             {
                establishUserConnection();
                readMessagesFromUser();
             } 
             catch (Exception e) 
             {
                 System.err.println(e.getMessage());
                 removeUser();
             }
        }
         /*
         * Connects user to server
         * @throws IOException if {@link ObjectInputStream#readUTF()} encounters an error
         */
         private void establishUserConnection() throws IOException 
         {
             // Get input and output streams from socket
             toUser = new ObjectOutputStream(userSocket.getOutputStream());
             fromUser = new ObjectInputStream(userSocket.getInputStream());
             // Read and save username and save OOS to user in outputToUsers in ChatServer class
             username = fromUser.readUTF();
             outputToUsers.add(toUser);
             writeToLog(username + " joined the chat.");
             writeToAll(username + " joined the chat.");
         }
         /**
         * Removes user from server
         */
         private void removeUser() 
         {
             // Decrease user counter and remove OOS to user
            connectedUsers--;
            outputToUsers.remove(toUser);
             writeToLog(username + " left the chat.");
             writeToAll(username + " left the chat.");
             // If server doesn't accept new users, start accepting them once again
             if (!acceptingNewUsers) acceptUsers();
         }
         /**
         * Continually read messages from user
         *
         * @throws IOException if {@link ObjectInputStream#readUTF()} encounters an error
         */
         private void readMessagesFromUser() throws IOException 
         {
             while (true)
                 writeToAll(String.format("%s wrote: %s", username, fromUser.readUTF()));
         }
    }
}

chatclient

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class ChatClient extends Application
{
      private ObjectOutputStream toServer = null; 
      private ObjectInputStream fromServer = null;
      private GridPane gridpane = new GridPane();
      private BorderPane mainPane = new BorderPane();
      private TextField tfUsername = new TextField(); 
      private TextField tfUserInput = new TextField(); 
      private TextArea ta = new TextArea();
      private String username = "";
      private String userinput = "";
      private Socket socket;

    public static void main(String[] args)
    {
        launch(args);
    }
    @Override
    public void start(Stage primaryStage) throws Exception 
    {
        // Panel p to hold the label and text field 
        BorderPane paneForTextField = new BorderPane(); 
        paneForTextField.setPadding(new Insets(5, 5, 5, 5));  
        paneForTextField.setStyle("-fx-border-color: green"); 
        gridpane.add(tfUsername, 0, 0);
        gridpane.add(tfUserInput, 0, 1);
        initializeUsernameTextField();
        initializeUserInputTextField();
        tfUserInput.setPrefWidth(400.0);
        gridpane.setPrefWidth(450.0);
        gridpane.setVgap(5.0);
        gridpane.setHgap(25.0);
        gridpane.setAlignment(Pos.CENTER);
        paneForTextField.setBottom(gridpane);
        ta.setPrefHeight(450);
        mainPane.setCenter(new ScrollPane(ta)); 
        mainPane.setBottom(paneForTextField); 
        initializePrimaryStage(primaryStage);
        tfUsername.setOnAction(e -> 
        { 
            if (!tfUsername.getText().equals(""))
            {
                username = tfUsername.getText().trim();
                connecToServer();
            }
        }); 
        if (!username.equals(""))
        {
            tfUserInput.setOnAction(e -> 
            { 
              // Get user input
            String UserInput = tfUserInput.getText();
            // Send string
            sendToServer(UserInput);
            // Get string
            receiveDataFromServer();
            writeToLog(userinput); 
            }); 
        }
    }
    private void initializeUsernameTextField()
    {
        tfUsername.setPrefWidth(400.0);
        tfUsername.promptTextProperty().set("Enter username here...");
    }
    private void initializeUserInputTextField()
    {
        tfUserInput.setPrefWidth(400.0);
        tfUserInput.promptTextProperty().set("Enter message here...");
    }
    private void initializePrimaryStage(Stage stage)
    {
        // Create a scene and place it in the stage 
        Scene scene = new Scene(mainPane, 450, 400); 
        stage.setTitle("Chat Client"); // Set the stage title 
        stage.setScene(scene); // Place the scene in the stage 
        stage.show(); // Display the stage 
    }
    private BorderPane getBorderPane() {return mainPane;}
    private void connecToServer()
    {
        establishServerConnection();
    }
    private void establishServerConnection()
    {
        try 
        { 
          socket = new Socket("localhost", 4999);  
          fromServer = new ObjectInputStream(socket.getInputStream()); 
          toServer = new ObjectOutputStream(socket.getOutputStream());
          sendToServer(username);
        } 
        catch (IOException ex) 
        { 
          ta.appendText(ex.toString() + 'n'); 
        } 
    }
    private void receiveDataFromServer()
    {
        try 
        {
            userinput = fromServer.readUTF();
        } catch (IOException ex) 
        {
            System.err.println(ex); 
        }
    }
    private void sendToServer(String s)
    {
        try 
        {
            toServer.writeObject(s);
            toServer.flush();
        } 
        catch (IOException ex) 
        {
            System.err.println(ex); 
        }
    }
    private void writeToLog(String s)
    {
        ta.appendText(tfUsername + "wrote: " + s + "n"); 
    }
}

tldr;

尝试连接到服务器时获取NullPoInterException,我找不到问题。

错误消息:

Exception in thread "Thread-5" java.lang.NullPointerException
    at chapter19.ChatServer$AddUserToChat.removeUser(ChatServer.java:171)
    at chapter19.ChatServer$AddUserToChat.run(ChatServer.java:143)
    at java.lang.Thread.run(Unknown Source)

属性 outputToUsers不是不化的,因此等于 null
这会导致拨打establishUserConnection的语句outputToUsers.add(toUser)时,会在AddUserToChat.run()中抛出一个例外。
捕获此例外,因此称为removeUser
在此方法中,语句outputToUsers.remove(toUser)导致新的异常。

最新更新