поток ввода-вывода Java блокирует поток на стороне сервера - PullRequest
2 голосов
/ 08 июля 2010

я работаю над подключением клиентского сокета.клиент является аппаратным устройством GPRS.Я получаю запрос от этого клиента на моем serversocket и затем открываю несколько потоков.Моя проблема заключается в том, что когда устройство / клиент закрывает сокет, то мой IO обнаруживает, что выдает исключение, но когда я отсоединяю батарею от устройства во время отправки запроса на сокет сервера, он блокируется без каких-либо исключений.кто-то предложил мне использовать setSOTimeout () для выхода из потока блокировки.

Я пробовал Socket.setSOTimeout (int).но это не работает в моем случае.Я отправляю свой код правильно.

//  inside main class--- 

    public class ServerSocketClass{
    public ServerSocketClass() {
    try{
        serverSocket = new ServerSocket(port);//creating a serversokcet on a port
    System.out.println("Server waiting for client on port " + 
    serverSocket.getLocalPort());
    } catch (Exception e) {
        e.printStackTrace();
    handleExceptions("errorServerSocketOpen.txt", e);
    System.exit(0);
}
try {
    while (true) {
        Socket clientSocket = serverSocket.accept();//accepting the client connection and //creating client socket

        new AcceptConnection(clientSocket);//calling the constructor of other //class to open a new thread
        System.out.println("constructor called.....");
    }
} catch (Exception e) {
    handleExceptions("errorClientSocketOpen.txt", e);
   }
  }
 }
//inside other class---


public class AcceptConnection implements Runnable {
    public AcceptConnection(Socket socket) {
    this.clientSocket = socket;
    if (clientSocket != null) {
        new Thread(this).start();
    }
    public void run() {
        // clientSocket.setSoTimeout(60000);// this is what i added.timeout on each client socket opened in threads
        InputStream inputStream = clientSocket.getInputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
        byte[] mainBuffer = new byte[2048];
        int len = -1, totalLength = 0;
        debugInfo = " GOING TO READ FROM SOCKET.... " + "\n";
        while ((len = inputStream.read(mainBuffer)) > -1) {
            totalLength = len;
        }//end of while
    } }//end of other class

Теперь моя проблема в том, что, когда открыто несколько потоков, и я отправляю данные от клиента, чем через 60 секунд он закрывает основной сокет и прекращает получать данные. И возникает ошибка readtimeout.

, пожалуйста, помогите мне и скажите, как моя цель может быть достигнута.

заранее спасибо

**

@ stephen

** окей Стивен понял, что ты пытаешься сказать ... ты прав в своем утверждении "Well yes ... that's what you told it to do." Возможно, я не в состоянии заставить тебя понять мою проблему или я не получаю логику setSoTimeout ()новичок в Яве.я хотел бы спросить еще раз ... вот как я создаю новый клиентский сокет для каждого клиентского соединения и открываю новый поток для каждого клиентского соединения.

    while (true) {
            Socket clientSocket = serverSocket.accept();//accepting the client connection and //creating client socket
                new AcceptConnection(clientSocket);//calling the constructor of other class to open a new thread
            System.out.println("constructor called.....");
        }
public void run() {
            // clientSocket.setSoTimeout(60000);// this is what i added.timeout on each uclient socket opened in threads
........................................
.......................................
}

Теперь я хочу сказать, если яоткрывая новый поток для нового клиентского соединения, и я отдельно помещаю setSoTimeout () в каждый объект клиентского соединения, тогда, если конкретный поток A блокируется на ввод-вывод во время чтения, то после истечения времени ожидания, установленного в setSoTimeout (50000), скажем, 50 секунд,только поток A должен выйти из чтения и выдать исключение, а не другие потоки, работающие одновременно, скажем, B, C, D. Но в моем случае после тайм-аута все потоки возвращаются после выдачи исключения, и фактически любое новое клиентское соединение выдает ту же ошибку иСерверное приложение перестает получать какие-либо данные на чтение.я хочу, чтобы только поток A выдавал исключение и выходил из чтения, не затрагивая другие объекты сокета клиента (или потоки).

Теперь я надеюсь, что рассказал вам все о своей путанице и проблеме.

Пожалуйста, помогите мне и большое спасибо.

1 Ответ

0 голосов
/ 08 июля 2010

Теперь моя проблема в том, что когда открыто несколько потоков, и я отправляю данные от клиента, то через 60 секунд он закрывает основной сокет и прекращает прием данных. И возникает ошибка тайм-аута чтения.

Что ж, да ... это то, что вы сказали ему сделать.

Как я уже сказал в своем ответе на ваш предыдущий вопрос, вы не можете различать эти случаи:

  • У клиента нет данных для отправки за определенный период.
  • Сеть разделена на определенный период.
  • Клиент исчез из сети.

Другой вариант, который у вас есть, - позвонить Socket.setKeepAlive(), чтобы включить TCP keepalive .Это приводит к тому, что периодически выполняется специальное квитирование "keepalive", чтобы гарантировать, что соединение TCP / IP все еще живо.К сожалению, не похоже, что вы можете установить интервал поддержки активности TCP / IP в Java.

EDIT

NIO не поможет.Когда я сказал «не могу» выше ... я имел в виду, что ФИЗИЧЕСКИ НЕВОЗМОЖНО сделать это.Вот аналогия, чтобы помочь вам понять.

Единственное сообщение между Outer WoopWoop и остальным миром - это письмо.Раз в неделю мой друг из Outer WoopWoop (который живет один) отправляет мне письмо, чтобы сообщить мне о сплетне.На прошлой неделе я не получил письмо от моего друга.Как я могу узнать, что:

  1. мой друг умер,
  2. мой друг не сплетничал на прошлой неделе,
  3. работники почты Outer WoopWoop бастовали,или
  4. все вышеперечисленное?

Правильный ответ: я не могу сказать.

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