Передача сокета - PullRequest
       5

Передача сокета

0 голосов
/ 09 марта 2011

У меня одновременно работает несколько классов, которые получают данные с сервера.Оба имеют настроенные сокеты.

Проблема в том, что, хотя я и передаю одни и те же данные между классами, когда данные поступают, они не совпадают.method:

        private boolean transferBroadcastData() {
            boolean success = false;

            try {           
                Vector<Client> clientsList =
                    onlineList.getClientsList();

                for (Client client : clientsList) {
                        ObjectOutputStream objectOutputStream =
                            client.getObjectOutputStream();
                            objectOutputStream.writeObject(clientsList);
                            objectOutputStream.flush();
                }


                success = true;

            } catch (Exception ioException) {
                ioException.printStackTrace();
            }

            return success;
        }

И вот метод получения:

        while (true) {
                try {
                    Object object = objectInputStream.readObject();

                    if (object instanceof Vector<?>) {
                        String x = "I got it:\n";

                        Vector<Client> clients = (Vector<Client>) object;

                        for(Client c : clients) {
                            x += "\n" + c;
                        }

                        JOptionPane.showMessageDialog(ClientManager.this, x);

                        usersPanel.addClientsToList((Vector<Client>) object);
                    }

                    else if (object instanceof Message)
                        messagePanel.appendText((Message) object);


                } catch (ClassNotFoundException classNotFoundException) {
                    statusPanel.updateStatus("Error reading from socket");
                }
            }

Когда я получаю Вектор на всех моих клиентах, элементы в нем различаются.Это не содержимое вектора, который я пытался передать.

Что мне не хватает?

1 Ответ

1 голос
/ 09 марта 2011

Вероятно, проблема связана с использованием Serialization / ObjectOutputStream.Когда объект сериализуется, ObjectOutputStream хранит внутренние записи, чтобы «оптимизировать» процесс сериализации, так что, если вы сериализуете один и тот же объект дважды, он просто повторяет идентификатор и предполагает, что объект не изменился .Например, если вы запустите код:

ObjectOutputStream oos = new ObjectOutputStream();
MyObject[] arr = new MyObject[]{myObject};
oos.write(myObject);
oos.write(arr);

, результат может выглядеть следующим образом (обратите внимание, не фактический формат, а пример):

[[myObject;id=357;foo=bar;baz=36;]]
[[MyObject[];id=358;data={id=357}]]

Обратите внимание, что массив не сериализует объектеще раз, а точнее просто идентификатор уже сериализованной версии.Сделав еще один шаг, если у вас есть код:

ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.write(myObject);

В итоге вы получите:

[[myObject;id=357;foo=bar;baz=36;]]
{id=357}

Обратите внимание, что , хотя объект изменил только внутренний идентификаторсериализовано .Хитрость в том, что когда вы пишете объекты, вам необходимо очистить внутреннее состояние ObjectOutputStream, что может быть достигнуто с помощью reset ().Из javadocs:

Сброс будет игнорировать состояние любых объектов, уже записанных в поток.Состояние сбрасывается, чтобы быть таким же, как новый ObjectOutputStream.

Поэтому, если вы возьмете предыдущий пример и добавите сброс:

ObjectOutputStream oos = new ObjectOutputStream();
oos.write(myObject);
myObject.setBaz(99999);
oos.reset();
oos.write(myObject);

В результате вы должны получить ожидаемое поведениеиз:

[[myObject;id=357;foo=bar;baz=36;]]
[[myObject;id=358;foo=bar;baz=99999;]]

Следует помнить, что вторая сериализация теперь будет считаться объектом , отличным от исходной сериализации.В зависимости от того, как вы переносите данные и внутренние отношения, вы должны быть осторожны, чтобы не сбрасывать поток слишком рано, если объекты обмениваются ссылками друг с другом, и вы хотите, чтобы эти отношения поддерживались.

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