2014-12-03 1 views
1

Я создаю HTTP-сервер в качестве проекта для класса, который я прислушиваюсь, в течение недели я застрял, пытаясь найти решение. У меня есть DataInputStream, и мне нужно дождаться клиента выслать запрос HTTP, может пройти несколько часов до, что происходит, так как соединение остается open.This мой кодБлокировать до тех пор, пока не будет доступен DataInputStream

DataInputStream dis=new DataInputStream(socket.getInputStream()); 
    DataOutputStream dos =new DataOutputStream(socket.getOutputStream()); 

    while(!socket.isClosed()){ 
     try{ 
      /**wait until there are new data in to the stream,if the connection is no more alive then close it*/ 
      while(dis.available()==0){ 
       if(alive==false){ 
        socket.close(); 
        break; 
       } 
      } 

      /*at this point the stream has new data ,or the alive attribute has been set to false */ 
      if(!socket.isClosed()){ 
       /*parse the request text */ 
       Request request=new Request(dis,this); 

       /*generate a response based on the request*/ 
       Response response=new Response(request,this); 

       /*send the response back to the client*/ 
       response.send(dos); 

       /*log the details of the communication*/ 
       Logger.log(toString(request,response,socket)); 

       /*if the request is bad formatted or it has its Connection header set to close , close the connection after sending the response*/ 
       if(request.isBadRequest() || !"keep-alive".equalsIgnoreCase(request.getHeader("Connection"))){ 
        close(); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
      break; 
     } 
    } 

на while(dis.available()==0) части я ждал потока, чтобы иметь какие-то данные, но проблема в том, что, если у меня много соединений, мой сервер начинает получать очень много времени, замедляя мой компьютер, поскольку он просто зависает, делая цикл снова и снова, не давая возможности процессору делать хорошее планирование. Если dis.available() был блокирующая запятая и тогда все было бы идеально. Любой обходной путь?

+0

Это не так, как вы обычно обрабатываете HTTP-запросы. Обычно ваш серверный сокет ожидает соединения. Как только у вас есть соединение, вы предполагаете, что данные должны поступать очень скоро, и если они не попадают в заданный тайм-аут (обычно не более минуты), вы закрываете соединение. – RealSkeptic

+0

@RealSkeptic, но что, если в первом запросе есть заголовок соединения, настроенный на сохранение?, Не должен ли я поддерживать соединение в ожидании, пока клиент не отправит следующий запрос? – SteveL

+0

Существует также истечение срока действия для keepalives. На реальных серверах он настраивается. Например, в Apache значение по умолчанию составляет 5 секунд, и они предупреждают вас, что увеличение его слишком сильно влияет на производительность. Идея keepalive заключается в том, чтобы позволить пользователю избежать накладных расходов на установление нового соединения, это не означает постоянное бесконечное соединение. – RealSkeptic

ответ

1

InputStreamsуже блок в методах чтения, пока данные отсутствуют.

Вам не нужен ни один из этих available() звонков или петель вокруг них.

Вы также должны отметить, что Socket.isClosed() возвращает true, если вы закрыли розетку. Он не сообщает, закрыл ли партнер соединение.

+0

Я сначала использовал метод readLine() для InputDataStream, и этот метод вместо блокировки возвращал значение null, когда там не было никаких данных. Я изменил его на read() ... теперь мне просто нужно найти способ сделать это выглядите элегантно (если вы видите мой код выше) – SteveL

+0

'readLine()' возвращает null * в конце потока. * Не 'когда нет данных'. Если вы получили нуль, сверстник отключился. – EJP

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

  • Нет связанных вопросов^_^