2011-01-16 3 views
0

Мне нужно иметь «стабильное» соединение с сервером.Нужно иметь «стабильное» TCP-соединение с сервером

  1. Клиент пытается подключиться к серверу каждые 5 (10, N) -секунд.

  2. После успешного подключения клиент получает данные с сервера.

  3. В случае прерывания обслуживания (например, выключения сервера) перейдите к шагу # 1.

Как проверить:

  1. Я запустить сервер

  2. Я запуск клиента (чтобы убедиться, что клиент получает данные с сервера)

  3. останавливается сервер

  4. Я жду 200 попыток клиента для подключения к серверу.

  5. Я перезапускаю сервер.

Сервер отправляет данные, но клиент не получает их. socket.connect(...) is sucessfull, но socket.getInputStream().read(byte[]) не является: Thread блоков на input.read(..).

Если я раскомментировать эту строку:

//socket.setSoTimeout(500); 

затем input.read(..) бросает TimeoutException.

Но сервер получает данные от клиента.

Где моя ошибка? Спасибо.

Часть кода клиента:

private void initSocket() { 
    try { 
     if (socket == null || socket.isClosed() == true 
       || socket.isConnected() == false) { 
      socket = new Socket(); 
      // socket.setSoTimeout(500); 
      InetSocketAddress socketAddress = new InetSocketAddress("192.168.1.3" 
        , 12344); 
      notifyDataListener(4); 
      socket.connect(socketAddress, 500); 
      notifyDataListener(5); 
     } 
    } catch (Throwable t) { 
     System.err.println(t); 
    } 
} 

private void closeSocket() { 
    try { 
     if (socket != null && socket.isClosed() == false) { 
      socket.close(); 
     } 
    } catch (Throwable t) { 
     System.err.println(t); 
    } 
} 

private byte[] buffer = new byte[1024]; 

public void run() { 
    while (isActive) { 
     try { 
      notifyDataListener(1); 
      initSocket(); 
      InputStream input = socket.getInputStream(); 
      int length = input.read(buffer); 
      if (length < 0) { 
       throw new EOFException("Was got -1"); 
      } 
      notifyDataListener(2); 
     } catch (Throwable t) { 
      closeSocket(); 
      notifyDataListener(3); 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException ie) { 
      } 
     } 
    } 
} 

На J2SE тот же код работает отлично. Ремонт соединений после многих неправильных попыток. Похоже, у Android есть лимиты с ограничениями сокетов (FileDescriptior?), Они берут их, но не освобождают после.

+0

Я пробовал свой код, и он отлично работает на моем устройстве (конечно, с использованием другого служебного адреса). – Shlublu

ответ

0

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

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

Первое, что вам нужно сделать, это переместить код socket.close() в finally {} операторы, которые немедленно освободят сокет, а не ожидают сбора мусора.

Смежные вопросы