Блок Java Socket ObjectInputStream

В Java Object Serialization вам необходимо создать ObjectOutputStream до ObjectInputStream как на стороне сервера, так и на стороне клиента, что я и сделал, но клиент будет работать до тех пор, пока ему не придется ждать данных с сервера (распечатайте сообщение «Готово» 3 ", затем подождите), а на стороне сервера код выполняется только до тех пор, пока он не дойдет до точки чтения первой информации от клиента (выведите" Готово 1 "и подождите). Что еще мне нужно сделать, кроме создания ObjectOutputStream перед ObjectInputStream? Из всех поисков, которые я видел, все они упоминают порядок создания объекта, и в одном случае они сказали, что нужно сбрасывать вывод сразу после его создания (как в примере 1), но это тоже не сработало.

Пример1

ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
dataOut.flush();
ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());

Сервер

@Override
public void run() {
    try {
        serverSocket = new ServerSocket(4554);
        serverRunning = true;
        while (serverRunning) {
            socket = serverSocket.accept();
            ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
            System.out.println("Done 1");

            String string = dataIn.readUTF();
            System.out.println("Done 2");

            int number = dataIn.readInt();
            System.out.println("Done 3");

            dataOut.writeUTF("String from server");
            System.out.println("Done 4");

            dataOut.writeInt(1);
            System.out.println("Done 5");

            System.out.println(string + " | " + number);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Клиент

    Socket socket = new Socket("localhost", 4554);
    ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
    ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
    System.out.println("Done 1");

    dataOut.writeUTF("String from client");
    System.out.println("Done 2");

    dataOut.writeInt(2);
    System.out.println("Done 3");

    String string = dataIn.readUTF();
    System.out.println("Done 4");

    int number = dataIn.readInt();
    System.out.println("Done 5");

    socket.close();
    System.out.println(string + " | " + number);

//Редактировать: Итак, если я заменю каждый writeUTF()writeInt() на writeObject(), а также поменяю каждый readUTF()readInt() на readObject() (добавив соответствующий состав для String и int), проблема исчезнет как на стороне сервера, так и на стороне клиента. Но я не понимаю, почему это так, есть ли объяснение такого поведения и исправление? Я бы использовал DataOuput/InputStream, но мне тоже нужно отправлять / получать объекты, поэтому DataOuput/InputStream мне не поможет.

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

exudong 06.12.2018 10:29

Почему вы используете сериализацию, когда используете только writeUTF/Int() и readUTF/Int()? Вы можете использовать DataInput/OutputStream и избежать всех этих осложнений. И какое отношение Example1 имеет к вашему фактическому коду? @exudong Вы не должны сбрасывать после каждой записи, и если есть буферизованный поток под ObjectOutputStream, вам действительно нужно сбрасывать его после создания, если вы собираетесь создать ObjectInputStream.

user207421 06.12.2018 10:36

@exudong Да, я тоже подумал, что это предложение о промывке сразу после создания было странным, но не помешает упомянуть, если только просто отфильтровать ответы по этому поводу, что еще вы хотите отладить, под этим комментарием, который я беру это то, что вы видели, что не так?

sValentin 06.12.2018 10:37

@ user207421 это был простой пример, но позже мне понадобятся и объекты, а не только String и Integer. Пример 1 был добавлен, чтобы показать, как этот человек сказал, что нужно делать, очистить после создания, что, на мой взгляд, тоже было странным.

sValentin 06.12.2018 10:40

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

user207421 06.12.2018 10:47

@sValentin, потому что нет очевидного сообщения об ошибке, поэтому я думаю, что его нужно отладить. например используйте tcpdump или wirehark, чтобы увидеть, действительно ли данные передаются по сети.

exudong 06.12.2018 11:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
62
0

Другие вопросы по теме