2014-12-03 21 views
1

我提出一個HTTP服務器作爲,我關心提醒着一個班的一個項目,一個星期我現在已經堅持試圖找到一個解決辦法。我有一個DataInputStream,我需要等待客戶端給我的HTTP請求,也可以通過時間在這之前發生,因爲連接保持open.This是我在while(dis.available()==0)部分我在等待流有一定的數據代碼的位置,直到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; 
     } 
    } 

,但問題是如果我有很多連接,我的服務器開始得到非常多的CPU時間,這會減慢我的計算機速度,因爲它只是一次又一次地循環執行循環,而沒有給CPU做好調度的機會。如果dis.available()是阻止逗號那麼一切都將是完美的。任何解決方法?

+0

這不是你通常如何處理HTTP請求。通常,您的服務器套接字等待連接。一旦建立了連接,就認爲數據應該很快到達,如果它們沒有在設定的超時範圍內(通常不超過一分鐘),那麼關閉連接。 – RealSkeptic 2014-12-03 15:20:50

+0

@RealSkeptic,但是如果第一個請求的連接頭設置爲保持活動狀態?如果不保持連接的活動並等待客戶端發送下一個請求? – SteveL 2014-12-03 15:23:07

+0

Keepalive還有一個到期超時。在真實的服務器中,它是可調整的。例如,在Apache中,默認值爲5秒,他們警告說增加太多會影響性能。 Keepalive的想法是允許用戶避免建立新連接的開銷,但它並不意味着永久連接。 – RealSkeptic 2014-12-03 15:32:19

回答

1

InputStreams已經塊在讀取方法,而沒有數據可用。

你不需要他們圍繞這些available()來電或循環的一個。

你還應該注意,Socket.isClosed()只返回true,如果已經關閉了socket。它不會告訴對方是否已關閉連接。

+0

我第一次使用InputDataStream的readLine()方法,而這個方法而不是阻塞在沒有任何數據的情況下返回null。我將它改爲read()...現在我只需要找到一種方法來實現它看起來很優雅(如果你看到我的代碼) – SteveL 2014-12-04 12:08:40

+0

'readLine()'在流結束時返回null *不是'沒有任何數據'。如果你得到空,對方已斷開連接。 – EJP 2017-12-31 03:50:12