readObject () генерирует EOFException, хотя данные еще не записаны - PullRequest
0 голосов
/ 30 января 2019

В настоящее время я пишу клиент-серверное приложение, в котором данные должны передаваться на сервер для обработки данных.Для построения соединения я использую ServerSocket и Socket, а для отправки данных я использую OutputStream + ObjectOutputStream на стороне клиента и InputStream + ObjectInputStream на стороне сервера.В данный момент соединение выполняется на локальном хосте.

Объект, который я пытаюсь передать, является сериализуемым классом, который содержит только параметры String.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что readObject () немедленно выбрасываетEOFException, как только OutputStreams клиента инициализируются (что приводит к инициализации InputStreams сервера одновременно) вместо ожидания ввода от клиента.

Я отправляю данные изклиент, использующий этот код:

    public void send(DataSet dataSet) {
        if (!clientStreamsEstablished) {
            initiateClientStreams();
        }
        try {
            out.writeObject(dataSet);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Этот метод вызывается только тогда, когда я нажимаю кнопку «отправить» в пользовательском интерфейсе, поэтому он не будет выполняться при запуске приложения.

В настоящее время данные (уже опробовано множество других подходов с циклом 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 dataSet никогда не инициализируется.

Однако, с моей точки зрения, readObject () должен заблокировать и ждать, пока клиент отправит ЛЮБЫЕ данные, прежде чем начать читать и выбрасыватьEOF.Мне кажется, что я прочитал половину Stack Overflow и других форумов в поисках ответа, но в найденных статьях обсуждаются только чтение файлов или только немедленные временные потоки, которые впоследствии закрываются.

Редактировать

Iинициализируйте соединение перед вызовом пользовательского интерфейса в моем основном методе:

    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();
        }
    }
...