Java - прослушивание сокета с помощью ObjectInputStream

Итак, у меня есть класс потока под названием «Клиент» каждый раз, когда сервер принимает соединение, он создает нового клиента .... Метод run прослушивает сообщения от клиента, и я использую ObjectInputStream ..

   do {            
         ObjectInputStream in = null;

        try {
            in = new ObjectInputStream(socket.getInputStream());
            String message = (String) in.readObject();
            System.out.println(message);
            }
            catch (ClassNotFoundException ex) {
                isConnected = false;
                System.out.println("Progoramming Error");
            }
            catch (IOException ex) {
                isConnected = false;
                System.out.println("Server ShutDown");
                System.exit(0);
            }
    } while(isConnected);

Моя проблема заключается в том, почему мне нужно создавать новый ObjectInputStream каждый раз, когда он зацикливается ... и если я закрою входной поток в конце цикла, и он снова зациклится для другого сообщения, я получу ошибку ... Пожалуйста, помогите кому-нибудь


person Mustafa    schedule 11.08.2011    source источник
comment
Вы не обязаны и не должны.   -  person JB Nizet    schedule 11.08.2011
comment
И получение ClassNotFoundException не является ни признаком того, что вы больше не подключены, ни ошибкой программирования. Это указывает на ошибку развертывания.   -  person user207421    schedule 11.08.2011
comment
Не могли бы вы пропустить, какие ошибки вы получаете, и было бы также полезно, если бы вы также разместили код клиента.   -  person beny23    schedule 12.08.2011
comment
isConnected() не является допустимым тестом для активного соединения. Соединение установлено до тех пор, пока вы не прочитаете конец потока или не появится IOException, отличный от SocketTimeoutException.   -  person user207421    schedule 25.01.2016


Ответы (1)


Создайте ObjectInputStream только один раз (вне цикла) для клиентского соединения, а затем поместите метод readObject в цикл.

Вот рабочий тестовый класс:

public class TestPrg {

    public static void main(String... args) throws IOException {
        ServerListener server = new ServerListener();
        server.start();

        Socket socketToServer = new Socket("localhost", 15000);
        ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());

        for (int i=1; i<10; i++) {
            try {
                Thread.sleep((long) (Math.random()*3000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Sending object to server ...");
            outStream.writeObject("test message #"+i);
        }
        System.exit(0);

    }

    static class ServerListener extends Thread {

        private ServerSocket serverSocket;

        ServerListener() throws IOException {
            serverSocket = ServerSocketFactory.getDefault().createServerSocket(15000);
        }

        @Override
        public void run() {
            while (true) {
                try {
                    final Socket socketToClient = serverSocket.accept();
                    ClientHandler clientHandler = new ClientHandler(socketToClient);
                    clientHandler.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class ClientHandler extends Thread{
        private Socket socket;
        ObjectInputStream inputStream;

        ClientHandler(Socket socket) throws IOException {
            this.socket = socket;
            inputStream = new ObjectInputStream(socket.getInputStream());
        }

        @Override
        public void run() {
            while (true) {
                try {
                    Object o = inputStream.readObject();
                    System.out.println("Read object: "+o);
                } catch (IOException e) {
                    e.printStackTrace();

                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

В этом примере строки отправляются через ObjectStream. Если вы получили исключение ClassNotFoundException (http://download.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#readObject ()) и используете независимую клиентскую и серверную программу, вы можете проверить, и клиент, и сервер имеют класс объекта для отправки в своих путях к классам.

person kvDennis    schedule 11.08.2011
comment
ооо, я вижу ... спасибо за этого приятеля .. я попробую позже .. и расскажу, как это происходит .... - person Mustafa; 11.08.2011
comment
Спать бессмысленно, и цикл чтения должен поймать EOFException и выйти из цикла чтения, когда его поймают. Все остальные IOExceptions, кроме SocketTimeoutException, также являются фатальными для соединения и должны выйти из цикла чтения. По любой причине сокет должен быть закрыт после выхода из цикла чтения. Здесь слишком много плохой практики. - person user207421; 25.01.2016
comment
Не будет ли один и тот же объект прочитан несколько раз? В ClientHandler? Или есть какая-то автоматическая функция внутри ObjectInputStream, которая предотвращает это? Почему этот цикл не читал один и тот же объект несколько раз? - person Lealo; 27.08.2017