Ошибка при получении объекта через ObjectInputStream с сервера - PullRequest
0 голосов
/ 23 февраля 2019

Я пишу простой пакет утилит для упрощения API java.io.Socket, но столкнулся со следующим скачком скорости: я до сих пор могу отправить класс сообщений (просто содержит поле типа Object, которое представляет любойданные) на сервер (я тестирую с использованием строк), и он может его прочитать. Однако, когда я пытаюсь снова прочитать сообщение, поток не распознает поступающие данные (я проверяю с помощьюin.available ()> 0).Буду признателен за любую помощь!

public class Client {

    private Socket client;
    private ObjectInputStream in;
    private ObjectOutputStream out;

    public Client (String hostName, int port) throws UnknownHostException, IOException {
        System.out.println("Establishing connection to server at " + hostName + ":" + port + "...");
        client = new Socket(hostName, port);
        System.out.println("Client connected. Client: " + client);

        this.out = new ObjectOutputStream(client.getOutputStream());
        this.out.flush();
        this.in = new ObjectInputStream(client.getInputStream());
    }

    public Object getFromServer () throws ClassNotFoundException, IOException {
        return in.readObject();
    }

    public void sendToServer (Object o) throws IOException {
        out.writeObject(o);
        out.flush();
    }

    public boolean dataAvailable () throws IOException {
        return in.available() > 0;
    }

    public void close () throws IOException {
        client.close();
    }
}

Поток на стороне сервера для обработки клиента (мне не нужно включать код серверов, поскольку он не имеет отношения к вводу-выводу:

public class ClientHandler extends Thread {

    private Socket client;
    private ObjectInputStream in;
    private ObjectOutputStream out;

    public ClientHandler (Socket socket) throws IOException {
        super();
        this.client = socket;
        this.out = new ObjectOutputStream(socket.getOutputStream());
        this.out.flush();
        this.in = new ObjectInputStream(socket.getInputStream());
    }

    @Override
    public void run () {
        String currentMessage = "";
        while (currentMessage != "/exit") {
            try {
                currentMessage = (String)((Message)in.readObject()).getData();
                out.writeObject(new Message(currentMessage.toUpperCase()));
                out.flush();
            } catch (ClassNotFoundException e) {
                System.err.println("ClassNotFoundException occured while processing client input");
                e.printStackTrace();
            } catch (IOException e) {
                System.err.println("IOException occured while processing client input");
                e.printStackTrace();
            }
        }
        try {
            client.close();
        } catch (IOException e) {
            System.err.println("IOException occured while trying to close client socket");
            e.printStackTrace();
        }
    }
}

Класс тестирования для клиента:

public class ClientMain {

    public static void main (String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
        Client client = new Client("localhost", 9090);

        BufferedReader sysIn = new BufferedReader(new InputStreamReader(System.in));

        String userMessage = "";

        while (userMessage != "/exit") {
            if (client.dataAvailable()) /*this if-statement never returns true*/ {
                String serverMessage = (String)((Message)client.getFromServer()).getData();
                System.out.println(serverMessage);
            }

            if (sysIn.ready()) {
                userMessage = sysIn.readLine();
                client.sendToServer(new Message(userMessage));
            }
        }

        client.close();
    }
}

Прежде чем кто-либо спросит, мой класс Message действительно реализует интерфейс Serializable, так что, вероятно, это не проблема.

1 Ответ

0 голосов
/ 23 февраля 2019

Я решил это.В классе ClientMain (в методе main) я разделил чтение пользовательского ввода и чтение сервера на два потока.Я сделал userMessage String статическим volatile, и теперь он работает по какой-то причине.Если бы кто-то мог ответить, хотя и сказал, почему мой подход не сработал, это было бы очень полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...