Java 为什么我的程序关闭时不打印堆栈跟踪或异常?
出于某种原因,当我加载程序时,它会立即关闭——加载顺序是RunServer.java>Main.java。它是一个加密的消息传递应用程序,只有当客户端或服务器接收到消息时,我才尝试解密消息 我知道这是一个愚蠢的代码量,但我不能进一步压缩它,因为我似乎无法复制错误在其他任何地方后6天+试图让它工作在一个较小的模型。非常感谢您的帮助。谢谢 编辑:好的,我发现这肯定与客户机类中的bigIntegrasModPow变量有关 编辑:它与客户端类方法“whileChatting()”中的调用有关。现在我得到了一个NullPointerException,我不确定它来自哪里 Main.javaJava 为什么我的程序关闭时不打印堆栈跟踪或异常?,java,rsa,inputstream,outputstream,Java,Rsa,Inputstream,Outputstream,出于某种原因,当我加载程序时,它会立即关闭——加载顺序是RunServer.java>Main.java。它是一个加密的消息传递应用程序,只有当客户端或服务器接收到消息时,我才尝试解密消息 我知道这是一个愚蠢的代码量,但我不能进一步压缩它,因为我似乎无法复制错误在其他任何地方后6天+试图让它工作在一个较小的模型。非常感谢您的帮助。谢谢 编辑:好的,我发现这肯定与客户机类中的bigIntegrasModPow变量有关 编辑:它与客户端类方法“whileChatting()”中的调用有关。现在我得到
import javax.swing.JFrame;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
assignValues();
client();
}
// Methods for the Main class //
// Method for giving values to each variable needed for the encryption algorithm //
private static void assignValues() {
RSAEncryption rsa = new RSAEncryption();
// Prompts the user for their desired bit length of keys //
rsa.setBitLengthDefault();
// Sets the values of the two prime keys that will be used for our encryption //
rsa.setPrimeP(rsa.getBitLength());
rsa.setPrimeQ(rsa.getBitLength());
// Sets the value of prime p totient //
rsa.setPrimePTotient(rsa.getPrimeP());
// Sets the value of prime q totient //
rsa.setPrimeQTotient(rsa.getPrimeQ());
// Sets the value of e //
rsa.setE();
// Sets the value of d //
rsa.setD(rsa.getE(), rsa.getPrimeP(), rsa.getPrimeQ());
// Sets the value of pq //
rsa.setPQ(rsa.getPrimeP(), rsa.getPrimeQ());
}
// Method that connects to the server and launches a client JFrame //
private static void client() {
// Instantiates the Client class, with the local IP address (This should be changed when in actual use) //
Client client = new Client("127.0.0.1");
// Sets up the default close situation (Which is when the JFrame is closed by the user) //
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Starts the running of the Client class as a thread //
client.startRunning();
}
}
Server.java
import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Server extends JFrame {
private JTextField userText;
private JTextArea chatWindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
// Constructor for the Server sub-class //
public Server() {
// Sets the title of the window //
setTitle("Samuels Encryption Server Service");
// Generates a new JTextField //
userText = new JTextField();
// Sets the JTextField to be un-editable //
userText.setEditable(false);
// Adds an action listener //
userText.addActionListener(new ActionListener(){
// Detects if the action is performed //
public void actionPerformed(ActionEvent event){
// Sends message with the contents of the action command //
sendMessage(event.getActionCommand());
// Sets the text field to empty //
userText.setText("");
}
});
// Adds the userText and sets the border layout to north of the screen //
add(userText, BorderLayout.NORTH);
// A new JTextArea is now instantiated //
chatWindow = new JTextArea();
// Adds the new JScrollPane, using the chatWindow variable and setting the border layout to center of the screen //
add(new JScrollPane(chatWindow));
// Use this to gain the full dimensions of the users screen //
// Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
// int width = (int) screenSize.getWidth();
// int height = (int) screenSize.getHeight();
// Sets the size of the whole window //
setSize(325,375);
// Sets visibility of the Swing components to true //
setVisible(true);
}
// Starts the Server class //
public void startRunning() {
BasicMethods bsc = new BasicMethods();
try {
// Instantiates the server with port '6789' and allows 100 users to queue //
server = new ServerSocket(6789, 100);
while(true) {
try {
// Waits for a user to connect //
waitForConnection();
// Sets up the i/o streams //
setupStreams();
// Sets up the GUI to read the input stream //
whileChatting();
} catch(EOFException eofException) {
// If an EOFException is given to the program, then this message is shown //
showMessage("\nThe server has ended the connection.");
} finally {
// Closes the streams and makes sure the text fields are un-editable //
closeEverything();
}
}
} catch(IOException ioException) {
// If an IOException is given to the program, then the stack trace is printed to the console //
ioException.printStackTrace();
}
}
// Method that waits for a user to connect to the server //
private void waitForConnection() throws IOException {
showMessage("Waiting for another user to connect...");
// Accepts any connection that the server receives //
connection = server.accept();
showMessage("\nYou have connected to " + connection.getInetAddress().getHostName());
}
// Sets the streams up in preparation for data to be sent //
private void setupStreams() throws IOException {
// Sets up the output stream //
output = new ObjectOutputStream(connection.getOutputStream());
// Flushes spare bytes out of the Client machine //
output.flush();
// Sets up the input stream //
input = new ObjectInputStream(connection.getInputStream());
showMessage("\nStreams are now setup!");
}
// Method that is run whilst the users are connected to each other //
private void whileChatting() throws IOException {
String message = "You are now connected!\n";
sendMessage(message);
// Sets the chat box to be editable //
ableToType(true);
do {
try {
message = (String) input.readObject();
// RSAEncryption rsa = new RSAEncryption();
// BigInteger bigIntegerModPow = new BigInteger(message).modPow(rsa.getD(), rsa.getPQ());
showMessage("\n" + new String(message));
} catch(ClassNotFoundException classNotFoundException) {
showMessage("\nThe server is unable to understand that String.");
}
} while(!message.equals("Client : END CONNECTION"));
}
// Method that sends a message using the output stream //
private void sendMessage(String message) {
try {
if (message.length() < 1 || message.length() > 50) {
} else {
showMessage("\nServer : " + message);
RSAEncryption rsa = new RSAEncryption();
rsa.setPrimeP(1024);
rsa.setPrimeQ(1024);
BigInteger p = rsa.getPrimeP();
BigInteger q = rsa.getPrimeQ();
rsa.setE();
rsa.setPQ(p, q);
BigInteger e = rsa.getE();
BigInteger pq = rsa.getPQ();
byte[] messageAsBytes = message.getBytes();
BigInteger bigIntegerModPow = new BigInteger(messageAsBytes).modPow(e, pq);
output.writeObject("Server : " + bigIntegerModPow);
// Flushes the output stream //
output.flush();
}
} catch(IOException ioException) {
// If an IOException is given to the program, then this message is printed to the console //
chatWindow.append("\nERROR CODE : 0");
ioException.printStackTrace();
}
}
// Method that does not allow the user to type to the text box and closes the i/o streams //
private void closeEverything() {
showMessage("\nClosing connections...\n");
// Sets the text box to be un-editable //
ableToType(false);
try {
// Closes the output stream //
output.close();
// Closes the input stream //
input.close();
// Closes the connection between Client and Server //
connection.close();
} catch(IOException ioException) {
// If an IOException is given to the program, then the stack trace is printed to the console //
ioException.printStackTrace();
}
}
// Method that prints a message to the text field //
private void showMessage(final String text) {
// Invokes a new runnable //
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Appends the message to the chat window //
chatWindow.append(text);
}
});
}
// Method that deals with permissions of the text field //
private void ableToType(final boolean tof) {
SwingUtilities.invokeLater(new Runnable() {
// Invokes a new runnable //
public void run() {
// Sets the userText field to be editable (depending on the input of the function //
userText.setEditable(tof);
}
});
}
}
import javax.swing.JFrame;
public class RunServer {
public static void main(String[] args) {
Server server = new Server();
server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
server.startRunning();
}
}
BasicMethods.java
public class BasicMethods {
// Method to print to the console in white text //
public void println(Object x) {
System.out.println(x);
}
// Method to print to the console in red text //
public void errorPrintln(Object x) {
System.err.println(x);
}
// Method to exit the program and return 0 //
public void exit(int x) {
System.exit(x);
}
}
这可能与对System.exit()的调用有关,这会杀死整个JVM,从而破坏堆栈的内容。使用调试器逐步完成它。所有分散在代码中的
exit()
调用是怎么回事?这是非常糟糕的做法。因此,我删除了所有exit()调用。我可以问一下,为什么它被列为坏习惯?当然,它会停止程序中的所有进程,因此一旦程序完成,就不需要垃圾收集器仍然在周围寻找要清理的东西等等,请在第一个字上加上更大的强调。我已经提到,我不能缩小它的大小。我不希望人们阅读所有这些内容,但我无法减少这些内容并保留错误。我已完成删除所有System.exit()调用。但是保留了方法。不要猜测答案。诚然,如果达到该值,调用System.exit()
确实会关闭整个JVM,但这需要Client.startRunning()
立即返回,而这似乎不是它想要的。
import javax.swing.JFrame;
public class RunServer {
public static void main(String[] args) {
Server server = new Server();
server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
server.startRunning();
}
}
public class BasicMethods {
// Method to print to the console in white text //
public void println(Object x) {
System.out.println(x);
}
// Method to print to the console in red text //
public void errorPrintln(Object x) {
System.err.println(x);
}
// Method to exit the program and return 0 //
public void exit(int x) {
System.exit(x);
}
}