Java Создание новых блоков ObjectInputStream - PullRequest
21 голосов
/ 14 апреля 2011

Я пытаюсь создать новый ObjectInputStream, используя InputStream, полученный из Socket. Вот мой код:

Это конструктор для моего класса MessageGetterSender. Программа не попадает в Checkpoint 4.

public MessageGetterSender(Socket socket) {

    System.out.println("MessageGetterSender: Checkpoint 1");

    this.socket = socket;

    // Get input and output streams
    try {
        System.out.println("MessageGetterSender: Checkpoint 2");

        InputStream is = socket.getInputStream();

        System.out.println("MessageGetterSender: Checkpoint 3");

        this.in = new ObjectInputStream(is);

        System.out.println("MessageGetterSender: Checkpoint 4");

    } catch (IOException ioe) {
        System.out.println("Could not get ObjectInputStream on socket: " + socket.getLocalPort());
    }

    try {
        this.out = new ObjectOutputStream(socket.getOutputStream());
    } catch (IOException ioe) {
        System.out.println("Could not get ObjectOutputStream on socket: " + socket.getLocalPort());
    }

    System.out.println("MessageGetterSender: Checkpoint 5");
}

Я создаю экземпляр нового объекта MessageGetterSender из класса, в котором я подключаюсь к серверу, чтобы получить сокет. Вот соответствующий код. Это конструктор для InstantMessageClass, класса, который создает экземпляр объекта MessageGetterSender:

public InstantMessageClient(String username) {

try {
    socket = new Socket("localhost", 5555);
} catch (IOException ioe) {
    System.out.println("Error: Could not connect to socket on port: " + serverPort);
}

messageGetterSender = new MessageGetterSender(socket);

...

Поскольку код не выполняется для Checkpoint 4, но он попадает в Checkpoint 3, я почти уверен, что виновником является экземпляр ObjectInputStream. Я не могу понять, почему, хотя. Есть идеи? Спасибо за помощь.

Ответы [ 3 ]

43 голосов
/ 28 сентября 2011

Просто чтобы расширить ответ FatGuy для других Googlers, которые находят это;Решение этой «проблемы курицы и яйца» состоит в том, чтобы каждая сторона сначала открывала выходной поток, очищала выходной поток, а затем открывала входной поток.

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
42 голосов
/ 14 апреля 2011

Когда вы создаете ObjectInputStream, в конструкторе класс пытается прочитать заголовок, который записал связанный ObjectOutputStream на другом конце соединения.Он не вернется, пока этот заголовок не будет прочитан.Поэтому, если вы видите конструктор «завис», это потому, что другая сторона сокета либо не использовала ObjectOutputStream, либо еще не сбросила данные.

1 голос
/ 27 января 2013

Вы также можете отложить инициализацию ObjectInputStream, пока данные не будут доступны в базовом потоке.

Этот подход работает независимо от порядка инициализации потока и особенно полезен, если один конец канала находится в коде библиотеки, который вы не можете изменить.

...