简体   繁体   中英

NullpointerException when trying to connect to localhost server

The title might not be very clear, and I not sure how I should phrase my question, but in short I am trying to create a "chat" program in java. I use 2 different files ChatServer and ChatClient.

How the program works is that you first open ChatServer and then ChatClient in order to connect to ChatServer. To Connect you need first to write a username in the first TextField and press enter. Then the program tries to connect you to the server, and here is where the problem starts.

Everytime I try to connect to the server I am getting nullpointerexception, and I can't understand why. I have tried for a long time to understand, but I am unable to see the error.

The point of the program is that mutliple ChatClients can connect to the ChatServer (Max 5 people) and write to each other. I know the question is very specific and I am hoping if anyone can point me in the right direction I would be very happy!

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;

Get nullpointerexception when trying to connect to the server, and I am unable to find the problem.

ERROR MESSAGE:

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)

The property outputToUsers is not inizialized and therefore equals null .
This causes an exception to be thrown within AddUserToChat.run() when calling establishUserConnection for the statement outputToUsers.add(toUser) .
This exception is caught so removeUser is called.
Within this method, the statement outputToUsers.remove(toUser) causes a new exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM