Я пишу простую программу обмена мгновенными сообщениями с использованием JavaFX и обнаружил исключение End Of File, и после нескольких часов отладки я не могу найти решение.
Моя программа состоит из двух частей: клиента исервер. Они посылают друг другу сериализованные объекты, содержащие всю необходимую информацию для выполнения требуемого действия. Я добавил дополнительные функции в свою программу, когда начал получать эту ошибку на сервере. С тех пор я удалил весь дополнительный код, но все еще получаю это сообщение об ошибке. Я не понимаю, почему я получаю эту ошибку, так как ни клиент, ни сервер не отправляют сообщение, означающее, что нет файла для достижения конца ??
Я закомментирую строку, где я вызываю метод«sendMessage ()», и это, кажется, решает проблему, но мне нужен этот метод для работы.
Ниже приведена копия класса сервера
package instachatfx.server;
public class ServerMain {
private static HashSet<ObjectOutputStream> writers;
private static ArrayList<User> users = new ArrayList<>();
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
writers = new HashSet<>();
try (ServerSocket listener = new ServerSocket(Constants.
while (true) {
new Handler(listener.accept()).start();
}
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
private static class Handler extends Thread {
private Socket socket;
private ObjectInputStream input;
private OutputStream os;
private ObjectOutputStream output;
private InputStream is;
private User user;
private String code;
public Handler(Socket socket) throws IOException {
this.socket = socket;
}
@Override
public void run() {
try {
is = socket.getInputStream();
input = new ObjectInputStream(is);
os = socket.getOutputStream();
output = new ObjectOutputStream(os);
while (socket.isConnected()) {
System.out.println("Waiting for packet...");
Packet inputmsg = (Packet) input.readObject();
if (inputmsg != null) {
switch (inputmsg.getHeader()) {
case REGISTER:
System.out.println("Case: REGISTER");
registerUser((User) inputmsg.getContent());
break;
case LOGIN:
System.out.println("Case: LOGIN");
loginUser((User) inputmsg.getContent());
break;
case CODE:
System.out.println("Case: CODE");
if (((String) inputmsg.getContent()).equalsIgnoreCase(code)) {
Constants.getDBManager().createNewUser(user);
loginUser(user);
} else {
sendMessage(PacketHeader.INCORRECT_CODE, "Incorrect code");
}
break;
case MESSAGE:
System.out.println("Case: MESSAGE");
sendToAll(inputmsg);
System.out.println(((Message) inputmsg.getContent()).getUser().toString() + ": " + ((Message) inputmsg.getContent()).getContent());
break;
default:
throw new HeaderNotFoundException("Server has no case for: " + inputmsg.getHeader().name());
}
}
}
} catch (SocketException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (HeaderNotFoundException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (EOFException ex)
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
} finally {
closeConnections();
}
}
private void sendToAll(Packet msg) throws IOException {
System.out.println("Send to all: " + msg.getHeader());
((Message) msg.getContent()).setUsers(users);
for (ObjectOutputStream writer : writers) {
writer.writeObject(msg);
writer.flush();
writer.reset();
}
}
private void sendToOthers(Packet msg) throws IOException {
System.out.println("Send to others: " + msg.getHeader());
((Message) msg.getContent()).setUsers(users);
for (ObjectOutputStream writer : writers) {
if (output != writer) {
writer.writeObject(msg);
writer.flush();
writer.reset();
}
}
}
/**
* Logs in a user
* @param u the user to be logged in
*/
private void loginUser(User u) {
try {
User us;
if ((us = Constants.getDBManager().loginUser(u)) != null) {
System.out.println("User found in database");
user = us;
writers.add(output);
users.add(user);
LoginMsg msg = new LoginMsg(user, users);
sendMessage(PacketHeader.LOGIN_SUCCESSFUL,
sendToOthers(new Packet(PacketHeader.MESSAGE, new Message(user.toString() + " has joined the chat", new User("SERVER", null))));
} else {
sendMessage(PacketHeader.LOGIN_FAIL, "Please check email and password");
}
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void registerUser(User u) throws IOException{
user = u;
if (Constants.getDBManager().checkDeuplicateEmail(u.getEmail())) {
sendMessage(PacketHeader.EMAIL_ALREADY_USED, "The email address " + u.getEmail() + " has already been used to make an account");
System.out.println("Email already exists");
return;
} else if ((code = sendVerificationEmail(u)) == null) {
sendMessage(PacketHeader.EMAIL_NOT_VALID, "There was an error sending the email to "
+ u.getEmail() + ". Please make sure the email is correct");
System.out.println("email failed sending");
return;
}
sendMessage(PacketHeader.WAIT_FOR_CODE, "Type in code in email");
}
/**
* Sends an email to the user to verify that it is correct
*
* @param u The user to send the email to
* @return null - the email failed sending <br>
* random sting - the email successfully sent using this verification
* code
*/
private String sendVerificationEmail(User u) {
String code = RandomString.getAlphaNumericString(10);
if (Constants.getSendEmail().sendEmail(u, code)) {
return code;
}
return null;
}
/**
* Sends a packet to only the client
*
* @param packetHeader for the client to tell how to read in the message
* @param msg the message for the client
*/
private void sendMessage(PacketHeader packetHeader, Object msg) throws IOException {
System.out.println("Send to client: " + packetHeader);
Packet message = new Packet(packetHeader, msg);
//ERROR OCCURS HERE
output.writeObject(message);
output.flush();
}
private void closeConnections() {
if (user != null){
users.remove(user);
}
try {
sendToAll(new Packet(PacketHeader.MESSAGE, new Message(user.toString() + " has left the chat", new User("SERVER", null))));
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
if (output != null){
writers.remove(output);
}
if (is != null) {
try {
is.close();
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (os != null){
try {
os.close();
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (input != null) {
try {
input.close();
} catch (IOException ex) {
Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
РЕДАКТИРОВАТЬ: вот трассировка стека
11 ноября 2019 г. 12:44:21 instachatfx.server.ServerMain $ Выполнение обработчика SEVERE: null java.io.EOFException at java.io.ObjectInputStream $ BlockDataInputStream.peekByte (ObjectInputStream.java:2950) в java.io.ObjectInputStream.readObject0 (ObjectInputStream.java:1534) в java.io.ObjectInputStream.readObject (ObjectInputStream.java:427) в instachatfx.server.ServerMain $ Handler.run (ServerMain.java:83)