我目前正在编写一个客户端-服务器应用程序,其中应将数据传输到服务器以处理数据。为了建立连接,我使用ServerSocket和Socket,并且为了发送数据,我在客户端使用OutputStream + ObjectOutputStream,在服务器端使用InputStream + ObjectInputStream。该连接当前正在localhost上运行。
我尝试传输的对象是仅包含String参数的可序列化类。
我现在面临的问题是,一旦初始化客户端的OutputStreams(导致同时初始化服务器的InputStreams),readObject()就会立即引发EOFException。来自客户的输入。
我使用以下代码从客户端发送数据:
public void send(DataSet dataSet) {
if (!clientStreamsEstablished) {
initiateClientStreams();
}
try {
out.writeObject(dataSet);
} catch (IOException e) {
e.printStackTrace();
}
}
仅当我在UI中单击“提交”按钮时才调用此方法,因此它将不会在应用程序启动时执行。
当前正在使用以下方法在服务器上读取数据(已经尝试了很多其他方法,无论是否使用while()循环等),
private void waitForInput(ObjectInputStream in, InputStream listeningPort) {
boolean dataReceived = false;
DataSet dataSet = null;
System.out.println("waiting ...");
while (!dataReceived) {
try {
Object temp = in.readObject(); // <-- EOFException is thrown here
boolean test = false;
if (temp instanceof DataSet) {
dataSet = (DataSet) temp;
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
break;
}
}
System.out.println("Test 2: " + dataSet.toString());
if (dataReceived) {
waitForInput(in, listeningPort);
}
}
服务器上的客户端线程一到达此行(请参见上面的代码注释),我就会得到以下堆栈跟踪:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at com.labdashboardserver.ClientThread.waitForInput(ClientThread.java:53)
at com.labdashboardserver.ClientThread.run(ClientThread.java:43)
Exception in thread "Thread-2" java.lang.NullPointerException
at com.labdashboardserver.ClientThread.waitForInput(ClientThread.java:65)
at com.labdashboardserver.ClientThread.run(ClientThread.java:43)
很明显,堆栈跟踪的第二部分包含NullPointerException的原因是由于EOFExcpetion数据集从未初始化。
但是,从我的角度来看,readObject()应该阻止并等待客户端发送任何数据,然后再开始读取它并抛出EOF。我感觉像是在阅读Stack Overflow和其他论坛的一半内容,寻找答案,但发现的文章仅讨论读取文件或仅在关闭后立即关闭的临时流。
我先在主要方法中调用UI,然后初始化连接:
public static void main(String[] args) {
connector = new LabConnector();
connector.run();
if (connector.getConnectionEstablished()) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new LabUI();
frame.setVisible(true);
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Error Message:\n" + e.getMessage() + "\nProgram shutting down!", "Critical Error", 0);
}
}
});
}
在LabConnector类中,我像这样初始化流和连接:
public void run() {
try {
establishConnection();
} catch (UnknownHostException e) {
retryConnection(e);
} catch (IOException e) {
retryConnection(e);
}
if (connectionEstablished) {
initiateClientStreams();
}
}
private void establishConnection() throws UnknownHostException, IOException {
client = new Socket(HOST_IP_ADRESS, HOST_PORT);
JOptionPane.showMessageDialog(null, "Connected to Server!");
connectionEstablished = true;
}
private void initiateClientStreams() {
try {
sendingPort = client.getOutputStream();
out = new ObjectOutputStream(sendingPort);
clientStreamsEstablished = true;
} catch (IOException e) {
e.printStackTrace();
}
}