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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема передачи сериализованного объекта, использую UDP 
V
    Опции темы
Dude03
Дата 22.4.2007, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Есть сервер, который читает сериализованный объект из файла и потом отсылает его клиенту.
Вот код сервера, который отправляет данные:
Код

UdpWrapper out = wrapper;
UdpWrapper in = wrapper;
// .......
db = readDb(in.nextLine()); // читаем сериализованный объект
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bos);
oout.writeObject(db);
out.println(bos.toString()); 
out.println("ok");


Вот кусочек класса UdpWrapper
Код

/**
     * Добавляет строку в выходной буфер
     * @param s строка
     */
    public void println(String s) {
        System.out.println(s);
        outData.add(s);
    }

    /**
     * Отправить массив строк
     */
    public void send() {
        if(outData.size() != 0) {
            StringBuffer stBuf = new StringBuffer();
            while(outData.size() != 0) {
                String s = outData.removeFirst();
                stBuf.append(s);
                stBuf.append("\n");
            }
            DatagramPacket Packet = new DatagramPacket(stBuf.toString().getBytes(), stBuf.length(), ip, port);
            try {
                sock.send(Packet);
            } catch(IOException e) { System.err.println("Failed I/O: " + e); }
        }
    }


А теперь принимающий код:
Код

private void getDataBase() {
        if(dbname != null) {
            try {
                w.println("get");
                w.println(dbname);
                w.send(ip, port);
                w.receive();
                ByteArrayInputStream bis = new ByteArrayInputStream(w.nextLine().getBytes());
                ObjectInputStream oin = new ObjectInputStream(bis);
                db = (RecordDb)oin.readObject();
                w.nextLine();
            } catch(Exception e) { e.printStackTrace(); }
        }
    }


w.nextLine().getBytes() - возвратит все байты сериализованного объекта.
Проблема в том, что(мало того) проверку на то, что пришел именно объект, надо производить вот так:
Код

if(Packet.getData()[0] == -84 && Packet.getData()[1] == -19) { // как-то странно изменилось магическое 
// число=( что думаете по этому поводу?
// другой код
}

Так и байты с кодом 0x98 меняются при передаче на 0x3f(вообще мистика). Проверял сравнением исходного сериализованного объекта с тем, что получается после отправки.

Это сообщение отредактировал(а) Dude03 - 22.4.2007, 11:10
PM MAIL   Вверх
LSD
Дата 22.4.2007, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Что-то вообще ничего из твоего кода не ясно. То ты говоришь, что используешь сериализацию. То в UdpWrapper передаешь массив строк.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Dude03
Дата 22.4.2007, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(LSD @  22.4.2007,  13:54 Найти цитируемый пост)
Что-то вообще ничего из твоего кода не ясно. То ты говоришь, что используешь сериализацию. То в UdpWrapper передаешь массив строк. 

Я передаю массив строк, чтобы потом его отправить одним пакетом. Разделители между строками - знаки переноса строки("\n").
Строки накапливаются:
Код

UdpWrapper w = wrapper;
w.println("get");
w.println(dbname);

А потом одним пакетом отсылаются:
Код

w.send(ip, port);

Когда клиенту приходит пакет, он смотрит на первые 2 байта, чтобы проверить магическое число(вдруг это объект), тогда весь он пишется в отдальную строку. Проблема в том, что байты как-то странно меняются(и магическое число, и некоторые байты самого объекта), и поэтому возникает эксепшен.

PM MAIL   Вверх
Alexandr87
Дата 22.4.2007, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


дыкий псых
***


Профиль
Группа: Завсегдатай
Сообщений: 1459
Регистрация: 27.11.2004
Где: Алматы, Казахстан

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



Протокол UDP не гарантирует доставку всех пакетов и не гарантирует, что доставленные пакеты будут выстроены в том порядке, в котором были отправлены. Может быть дело в этом? Попробуй посмотреть каким-ндь анализатором траффика, типа wireshark, в каком порядке пакеты к тебе приходят.
PM Jabber   Вверх
Dude03
Дата 22.4.2007, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Alexandr87 @  22.4.2007,  14:42 Найти цитируемый пост)
Протокол UDP не гарантирует доставку всех пакетов и не гарантирует, что доставленные пакеты будут выстроены в том порядке, в котором были отправлены. Может быть дело в этом? Попробуй посмотреть каким-ндь анализатором траффика, типа wireshark, в каком порядке пакеты к тебе приходят.

нет, дело не в этом. У меня одна команда - один пакет с ответом. Пока первая команда не была отбработана, то второй не будет.

Вот небольшой пример, который показывает проблему=(. Необходимо смотреть файл Primer.java. Все остальное - это то, что сериализуется.

Нечто происходит именно, когда происходит операция stringDb.getBytes(). Так что
Код

if(new String(stringDb.getBytes()).equals(stringDb)) {
                System.out.println("Ok!!!");
            } else {
                System.out.println("Failure=(");
            }

выведет "Failure=(".
Конечно, может быть проблема в том, что джава отводит на char 2 байта. Или может проблема в кодировке.

Это сообщение отредактировал(а) Dude03 - 22.4.2007, 15:34

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  primer.rar 5,53 Kb
PM MAIL   Вверх
LSD
Дата 22.4.2007, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Вот объясни зачем нужно вначале преобразовывать массив байт в строку (при том что там явно содержатся бинарные данные), а затем из строки снова получать массив байт?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Dude03
Дата 22.4.2007, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(LSD @  22.4.2007,  16:19 Найти цитируемый пост)
Вот объясни зачем нужно вначале преобразовывать массив байт в строку (при том что там явно содержатся бинарные данные), а затем из строки снова получать массив байт? 

Просто, когда писал код, я не подумал, что может быть такие траблы. 
И все-таки, как исправить?
PM MAIL   Вверх
LSD
Дата 22.4.2007, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(Dude03 @  22.4.2007,  17:27 Найти цитируемый пост)
И все-таки, как исправить?

Передавай в DatagramPacket сразу данные из ByteArrayOutputStream, без всяких строк.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Dude03
Дата 22.4.2007, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(LSD @  22.4.2007,  16:59 Найти цитируемый пост)
Передавай в DatagramPacket сразу данные из ByteArrayOutputStream, без всяких строк. 

Ну лады. Просто лень двигатся было=). Уже переписал.
PM MAIL   Вверх
COVD
Дата 22.4.2007, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Максимальная длина пакета UDP приблизительно от 500 до 1500 байт.  UDP - не лучший выбор для вашей задачи.
PM MAIL   Вверх
LSD
Дата 22.4.2007, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(COVD @  22.4.2007,  19:06 Найти цитируемый пост)
Максимальная длина пакета UDP приблизительно от 500 до 1500 байт.  UDP - не лучший выбор для вашей задачи.

Полностью согласен.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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