.read () создает прерывистое исключение SocketTimeoutException, даже если данные должны быть - PullRequest
1 голос
/ 03 августа 2011

Я работаю над веб-сервером для Android, и, хотя я потратил несколько дней, пытаясь это исправить, я в своем уме с этой конкретной ошибкой.Я пытаюсь прочитать запрос из браузера, и код работает в большинстве случаев нормально, но примерно 5% запросов не выполняются, и он генерирует случайные исключения SocketTimeoutException, даже не читая ни одного символа из Socket.

Я проверил это в разных браузерах, и это происходит со всеми из них, так что, скорее всего, проблема на моем конце.Вот соответствующий код, урезанный насколько это возможно:

public class ServerThread extends Thread {

private ServerSocket ss = null;
private boolean isRunning;

private ExecutorService threadPool = new ThreadPoolExecutor(2, 12,
          60L, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(),
          Executors.defaultThreadFactory(), 
          new ThreadPoolExecutor.CallerRunsPolicy());

public ServerThread() {
}

public synchronized void run() {
    ss = new ServerSocket(8080, 1);
    isRunning = true;

    while (isRunning) {
        Socket clientSocket = null;

        try {
            if (ss != null) {
                clientSocket = ss.accept();
                if (isRunning) {
                    this.threadPool.execute(new HTTPSession(clientSocket));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}

И:

public class HTTPSession implements Runnable {

private Socket mSocket = null;

public HTTPSession (Socket s) {
    mSocket = s;
}


public void run() {

    InputStream ips = null;

    try {
        mSocket.setSoTimeout(15000);
        ips = mSocket.getInputStream();
        ips.read();
    }
    catch (Exception e) {
        e.printStackTrace();
        Log.v("HTTPSession", "Socket connected: " + mSocket.isConnected() + ", Socket closed: " + mSocket.isClosed() + ", InputShutdown: " + mSocket.isInputShutdown());
    }
    finally {
            try { ips.close(); } catch (IOException ioe) {  }
            try { mSocket.close(); } catch (IOException ioe) {  }
    }

}
}

Итак, ServerThread принимает соединение, HTTPSession пытается прочитать из сокета, а иногда выдаетSocketTimeoutException после истечения 15 секунд.

Выходные данные оператора Log в перехвате в этом случае: Socket connected: true, Socket closed: false, InputShutDown: false

Что дает?Конечно, 15 секунд достаточно, и кажется маловероятным, что обычные веб-браузеры просто не отправляют никаких данных, так почему я не могу их прочитать?

Буду признателен за любую информацию по этой проблеме.

Ответы [ 2 ]

1 голос
/ 04 августа 2011

SocketTimeoutException означает только одно: данные не были доступны в течение периода ожидания.Так что да, может быть, ваш тайм-аут слишком короткий, и да, браузер не отправил его в течение периода ожидания, или, по крайней мере, он не достиг буфера приема сокета сервера в течение периода ожидания.

Я быскажем, 15 секунд немного агрессивно для таймаута на стороне сервера.30 секунд до пары минут было бы больше похоже на это.

0 голосов
/ 04 августа 2011

Я не вижу причин, по которым этот код не будет работать таким образом, если, как вы сказали, браузер просто ничего не отправляет. Вы можете изменить ips.read(); на System.out.println(ips.read());, чтобы быть уверенным в этом. Если вы видите, что байт появляется на stdout, то браузер что-то отправил. Я полагаю, что в вашем полном коде вы неправильно распознаете конец запроса и продолжаете ждать получения дополнительных данных. Через 15 секунд вы истечете. Но это только предположение. Если вы опубликуете какой-либо код, демонстрирующий проблему, кто-то может дать вам окончательный ответ.

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