[英]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. 标题可能不太清楚,我不确定应该如何表达我的问题,但总之,我试图在Java中创建一个“聊天”程序。 I use 2 different files ChatServer and ChatClient.
我使用2个不同的文件ChatServer和ChatClient。
How the program works is that you first open ChatServer and then ChatClient in order to connect to ChatServer. 该程序的工作方式是先打开ChatServer,然后打开ChatClient以便连接到ChatServer。 To Connect you need first to write a username in the first TextField and press enter.
要进行连接,您需要首先在第一个TextField中输入用户名,然后按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. 每当我尝试连接到服务器时,都会得到nullpointerexception,但我不明白为什么。 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. 该程序的重点是,多个ChatClient可以连接到ChatServer(最多5人)并互相写入。 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; TLDR;
Get nullpointerexception when trying to connect to the server, and I am unable to find the problem. 尝试连接到服务器时获取nullpointerexception,但我找不到问题。
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
. 属性
outputToUsers
未初始化,因此等于null
。
This causes an exception to be thrown within AddUserToChat.run()
when calling establishUserConnection
for the statement outputToUsers.add(toUser)
. 这将导致一个异常内抛出
AddUserToChat.run()
调用时establishUserConnection
的声明outputToUsers.add(toUser)
。
This exception is caught so removeUser
is called. 捕获此异常,因此调用
removeUser
。
Within this method, the statement outputToUsers.remove(toUser)
causes a new exception. 在此方法中,语句
outputToUsers.remove(toUser)
导致新的异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.