Странное поведение сокета Java (подключается, но не отправляется) - PullRequest
0 голосов
/ 22 мая 2010

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

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

Когда я пытаюсь подключиться в третий раз, кажется, что соединение проходит (метод ServerSocket.accept () проходит, и ObjectOutputStream успешно создан). Однако данные не передаются. Метод inputStream.readUnshared () просто блокирует.

Я принял следующие меры предосторожности при использовании памяти:

  1. Когда приходит время закрыть сокеты, все запущенные потоки останавливаются, и все объекты обнуляются.
  2. После каждого метода writeUnshared () вызов ObjectOutputBuffer промыть и сбросить.

Кто-нибудь сталкивался с подобной проблемой, или у кого-нибудь есть предложения? Боюсь, мой проект довольно большой, поэтому копирование кода проблематично.

Проект сводится к следующему:

СЕРВЕР ГЛАВНАЯ

ServerSocket serverSocket = new ServerSocket(port);

while (true) {
    new WorkThread(serverSocket.accept()).start();
}

РЕЗЬБА РАБОТА (СЕРВЕР)

public void run() {
    ObjectInputBuffer inputBuffer = new ObjectInputBuffer(new BufferedInputStream(socket.getInputStream()));

    while (running) {
         try {
              Object myObject = inputBuffer.readUnshared();

              // do work is not specified in this sample
              doWork(myObject);
         } catch (IOException e) {   
              running = false;
         }
    }

    try {
         inputBuffer.close();
         socket.close(); 
    } catch (Exception e) {
         System.out.println("Could not close.");
    }
}

КЛИЕНТ

public Client() {
    Object myObject;
    Socket mySocket = new Socket(address, port);

    try {
         ObjectOutputBuffer output = new ObjectOutputBuffer(new BufferedOutputStream(mySocket.getOutputStream()));

         output.reset();
         output.flush();
    } catch (Exception e) {
         System.out.println("Could not get an input.");
         mySocket.close();
         return;
    }

    // get object data is not specified in this sample. it simply returns a serializable object
    myObject = getObjectData();

    while (myObject != null) {
         try {
              output.writeUnshared(myObject);
              output.reset();
              output.flush();
         } catch (Exception e) {
              e.printStackTrace();
              break;
         } // catch
    } // while

    try {
         output.close();
         socket.close();
    } catch (Exception e) { 
         System.out.println("Could not close.");
    }
}

Спасибо всем, кто сможет помочь!

Ответы [ 2 ]

2 голосов
/ 22 мая 2010

(1) Что такое ObjectInputBuffer и ObjectOutputBuffer? Вы имели в виду ObjectInputStream & ObjectOutputStream?

(2) Если это так, вызов метода reset () сразу после создания ObjectOutputStream является пустой тратой времени и пропускной способности.

(3) Почему вы печатаете «не удалось получить данные» для исключения, создающего поток вывода?

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

(5) Вы предполагаете, что любое IOException при чтении означает конец потока. Только EOFException означает это. Любое другое IOException должно быть напечатано или зарегистрировано. Очевидно, вы получаете здесь другое исключение и игнорируете его.

(6) Почему вы продолжаете посылать один и тот же объект?

0 голосов
/ 22 мая 2010

Из API ObjectInputStream для readUnshared ():

Считывает «неразделенный» объект из ObjectInputStream.Этот метод идентичен readObject, за исключением того, что он запрещает последующим вызовам readObject и readUnshared возвращать дополнительные ссылки на десериализованный экземпляр, полученный через этот вызов.

Может ли это быть проблемой?Вместо этого используйте readObject ().

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