Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Клиент виснет при ожидании данных, ObjectInputStream 
:(
    Опции темы
Norb
Дата 28.2.2008, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 26.1.2007

Репутация: нет
Всего: нет



Передо мной стоит задача - написать сервер и клиент подобия ICQ,  но для локальной сети. Функциональность конечно точно такая же не требуется, главное - передача сообщений. Для этого создал класс Message и кидаюсь его объектами через ObjectInputStream и ObjectOutputStream. В общем всё нормально, сообщения приходят (пока хотя бы на сервер). Правда в начале столкнулся с той же проблемой, что и господин sith в теме ObjectInputStream - программа виснет . Причём тоже не мог её решить, в том числе и тем способом, который был указан там. Объяснить каким именно образом проблема разрешилась сам точно не могу, но ситуация изменилась когда объект класса ObjectOutputStream стал объявлять до объекта ObjectInputStream. Теперь же суть проблемы вот в чём - клиент должен постоянно находиться в состоянии ожидания входящих сообщений, то есть должен быть цикл, что-то вроде этого:
Код

                Socket s = new Socket(cw.ip.getText(), 3512);

                ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
                ObjectInputStream in = new ObjectInputStream(s.getInputStream());

                Message m = new Message(0);

...

                while (s.isConnected()) {
                    try {
                        m = (Message) in.readObject();
                           // обработка входящих сообщений
                    }
                    catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }

Но как раз в этом месте программа виснет и не подаёт признаков жизни. Что делать не знаю, ведь на сервере реализация ожидания сообщений аналогичная и работает превосходно. Причём сервер не виснет и если объект ObjectInputStream объявлять раньше ObjectOutputStream
Код

           ServerSocket s = new ServerSocket(port);
           Socket incoming = s.accept();

            ObjectInputStream in = new ObjectInputStream(incoming.getInputStream());
            ObjectOutputStream out = new ObjectOutputStream(incoming.getOutputStream());

.......

            while (incoming.isConnected()) {
                try {
                    Message mess = (Message) in.readObject();
                    // обработка входящих сообщений
                }
                catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }

Подскажите, пожалуйста, что делать, заранее спасибо!
PM MAIL   Вверх
COVD
Дата 28.2.2008, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 11
Всего: 43



чего-то у вас в коде все читают, а никто не пишет. А вообще, использование RMI в вашей задаче было бы уместно.


Это сообщение отредактировал(а) COVD - 28.2.2008, 23:42
PM MAIL   Вверх
sith
Дата 29.2.2008, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 11.2.2007

Репутация: 1
Всего: 1



Norb, ох прикольно конгда темы годичной давности возвращаються smile  
... потеме скажу следующее... этот проектик я так и не закончил так как в дальнейшем запутался с потоками... сейчас все обдумав с высоты уже приобретенного опыта скажу что RMI это точто здесь нужно... ведь фактически то что делаешь ты и я это тоже самое, только самописное... а это технология уже существует и живет... так что  я думаю в данном случае велосипед нет смысла изобретать... смотри в стороно RMI


--------------------
Там где ты ставишь глупые смайлики, я вбиваю восклицания знаки!!!
PM MAIL   Вверх
niasilil
Дата 5.3.2008, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.6.2007
Где: USA

Репутация: нет
Всего: 9



Цитата(Norb @ 28.2.2008,  22:59)
Но как раз в этом месте программа виснет и не подаёт признаков жизни. Что делать не знаю, ведь на сервере реализация ожидания сообщений аналогичная и работает превосходно. 

поставить сокет таймаут на 100 миллисекунд. Программа будет в режиме ожидания это время, потом будет проверять очередь сообщений - есть ли что то чтобы послать. Примерно так
Код

public class Connector extends Thread {

    private Socket socket;
    private InputStreamReader isr;
    private BufferedReader br;
    private OutputStreamWriter osw;
    private PrintWriter pw;
    private ArrayList<String> out = new ArrayList<String>();
    private boolean stop = false;
    private final int TIMEOUT = 200;

    /** Logger. */
    private Logger logger = Logger.getLogger("Connector");
    private boolean toSend;

    public Connector(Socket socket) {
        this.socket = socket;

        try {
            this.socket.setSoTimeout(TIMEOUT);

            isr = new InputStreamReader(socket.getInputStream());
            br = new BufferedReader(isr);

            osw = new OutputStreamWriter(socket.getOutputStream());
            pw = new PrintWriter(osw, true);

            logger.info("Socket streams initialized");
        } catch (IOException e) {
            logger.warning("Socket failed " + e.getMessage());
        }
    }

    @Override
    public void run() {
        try {
            while (!stop) {
                try {
                    String result;

                    result = br.readLine();
                    logger.info("Received message " + ": " + result);

                    if (result != null || !result.trim().isEmpty()) {
                        // do something;
                    }
                } catch (SocketTimeoutException e) {
                    // do nothing
                }

                if (toSend) {
                    send();
                }
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Network failed", "Network failed",
                    JOptionPane.WARNING_MESSAGE);
            logger.severe("Socket failed " + e.getMessage());
        }
    }

    /**
     * Sends the data
     */
    private void send() {
        synchronized (out) {
            for (String s : out) {
                pw.println(s);
                pw.flush();
                logger.info("Message is sent: [" + s + "]");
            }
            out.clear();
            // set flag for sending
            toSend = false;
        }
    }

    public void addMessageOut(String msg) {
        synchronized (out) {
            out.add(msg);
        }
        toSend = true;
        logger.info("outgoing message added: " + msg);
    }
}

ну или асинхронный клиент с разными threads для send и receive

Это сообщение отредактировал(а) niasilil - 5.3.2008, 21:15


--------------------
SCJP 5.0, SCJD
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.1058 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.