Проблема взаимоблокировки Java

Я использую java-сокеты для связи. На стороне клиента у меня есть некоторая обработка, и в этот момент я отправляю объект в cient. Код выглядит следующим образом:

while (true) {
  try {
    Socket server = new Socket("localhost", 3000);
    OutputStream os = server.getOutputStream();
    InputStream is = server.getInputStream();

    CommMessage commMessage = new CommMessageImpl();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(commMessage);
    os.write(bos.toByteArray());
    os.flush();

    byte[] buff = new byte[512];
    int bytesRead = 0;
    ByteArrayOutputStream receivedObject = new ByteArrayOutputStream();
    while ((bytesRead = is.read(buff)) > -1) {
      receivedObject.write(buff, 0, bytesRead);
      System.out.println(receivedObject);
    }
    os.close();
    Thread.sleep(10000);
  } catch (IOException e) {
  } catch (InterruptedException e) {
  }
}

Далее на стороне сервера у меня есть следующий код для чтения объекта и записи ответа (это просто эхо-сообщение)

public void startServer() {
  Socket client = null;
  try {
    server = new ServerSocket(3000);
    logger.log(Level.INFO, "Waiting for connections.");
    client = server.accept();
    logger.log(Level.INFO, "Accepted a connection from: " + client.getInetAddress());
    os = new ObjectOutputStream(client.getOutputStream());
    is = new ObjectInputStream(client.getInputStream());

    // Read contents of the stream and store it into a byte array.
    byte[] buff = new byte[512];
    int bytesRead = 0;
    ByteArrayOutputStream receivedObject = new ByteArrayOutputStream();
    while ((bytesRead = is.read(buff)) > -1) {
      receivedObject.write(buff, 0, bytesRead);
    }

    // Check if received stream is CommMessage or not contents.
    CommMessage commMessage = getCommMessage(receivedObject);
    if (commMessage != null) {
      commMessage.setSessionState(this.sessionManager.getState().getState());
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(bos);
      oos.writeObject(commMessage);
      os.write(bos.toByteArray());
      System.out.println(commMessage.getCommMessageType());
    } else {
      processData(receivedObject, this.sessionManager);
    }
    os.flush();
    } catch (IOException e) {
    } finally {
      try {
        is.close();
        os.close();
        client.close();
        server.close();
      } catch (IOException e) {
    }
  }
}

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


person markovuksanovic    schedule 09.05.2010    source источник


Ответы (1)


И клиент, и сервер пытаются прочитать весь входной поток (т. е. все до EOF), но ни один из них не отправляет EOF (путем вызова shutdownOutput() в сокете).

Почему вам нужно временно хранить данные объекта в ByteArrayOutputStream? Это, вероятно, было бы легче исправить, если бы вы читали непосредственно из входного потока сокета.

person finnw    schedule 09.05.2010
comment
Спасибо, я попробую решение сегодня позже... Но причина, по которой я использую ByteArrayOutputStream, заключается в том, что я не знаю, что придет от клиента - поток может содержать один из двух типов объектов. Итак, что я делаю, так это то, что я полностью читаю поток и пытаюсь преобразовать в один объект - если это не удается, это может быть только другой объект (или ошибка :)). Как вы думаете, я должен сделать это как-то по-другому? - person markovuksanovic; 09.05.2010
comment
Просто прочитайте его в объект и используйте instanceof. Я не вижу, как то, что вы делаете, добавляет что-то к этому, вам все равно придется это делать. - person user207421; 09.05.2010
comment
Ты прав. Я должен сделать некоторый рефакторинг, очевидно. Спасибо что подметил это. - person markovuksanovic; 09.05.2010