簡體   English   中英

接收http請求時,簡單的Web服務器掛起

[英]Simple web server hangs when receiving http request

我正在寫一個簡單的Web服務器,代碼片段:

 ServerSocket server = new ServerSocket(80);  
  Socket client=server.accept();  
  InputStream in=client.getInputStream();  
  OutputStream out=client.getOutputStream();  
  int val = -1;  
  while ((val = in.read()) != -1) {  
    System.out.print((char) val);  
  }   
  BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( out));  
  writer.write("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\nhello world!");  
  writer.close();  
  out.close();  
  in.close();

我在我的電腦上運行它,然后在Firefox中訪問http://127.0.0.1 頁面掛起,無法顯示“hello world”。我認為問題發生在while ((val = in.read()) != -1) ,如何解決?

HTTP(至少1.1版本)允許打開連接。 然后請求以空行結束(即"\\r\\n\\r\\n" ),如果它不是帶有內容的POST或PUT請求。 在此之后,客戶端可以在同一連接上發送下一個請求。

因此,您必須至少讀取輸入以掃描空行。


編輯:為了澄清這一點,來自RFC 2616 (定義HTTP 1.1)的一些引用。

部分4.1,消息類型

請求(第5節)和響應(第6節)消息使用RFC 822 [9]的通用消息格式來傳輸實體(消息的有效載荷)。 兩種類型的消息都包括一個起始行,零個或多個標題字段(也稱為“標題”),一個空行(即CRLF前面沒有任何內容的行),表示標題字段的結尾,可能還有一個郵件正文。

  generic-message = start-line *(message-header CRLF) CRLF [ message-body ] start-line = Request-Line | Status-Line 

因此,消息頭和消息體由空行(起始行之后的第一個)分隔。

4.3消息正文

HTTP消息的消息體(如果有的話)用於攜帶與請求或響應相關聯的實體體。 [...]

消息中允許消息正文的規則因請求和響應而異。

通過在請求的消息頭中包含Content-Length或Transfer-Encoding頭字段來指示請求中消息體的存在。 如果請求方法的規范(第5.1.1節)不允許在請求中發送實體主體,則消息主體不得包含在請求中。 服務器應該在任何請求上讀取和轉發消息體; 如果請求方法不包含實體主體的定義語義,那么在處理請求時應該忽略消息主體。

因此原則上,客戶端必須只在方法允許時發送一個正文,但是服務器應該忽略多余的消息體,如果它們是在不支持它的方法上發送的。 並且Content-LengthTransfer-Encoding頭字段指示正文的存在。

第9節的小節定義了各個方法。

  • 9.2選項
    • 可以包含一個正文,但意義沒有定義
  • 9.3 GET
    • 不能包含任何身體
  • 9.4頭
    • 不能包含任何身體
  • 9.5 POST
    • 應該(或必須?)包含一個身體
  • 9.6 PUT
    • 應該(或必須?)包含一個身體
  • 9.7刪除
    • 不能包含任何身體
  • 9.8追蹤
    • 不能包含任何身體
  • 9.9連接
    • (此方法保留)

無論如何,無論客戶端是否發送正文,以及它是否重新使用連接以進行下一個請求,通常都不會在讀取響應之前關閉連接,否則您的服務器根本無法重新發送響應。 因此,您在閱讀請求時無法等待結束,但必須以某種方式知道何時結束發送您的回復。

對於只處理獲取請求的簡單hello world服務器,您可以簡單地說“直到第一個空行”。

對於真實的服務器(即外部世界可見的服務器),您至少應該解析請求,忽略任何正文,並以不同於GET的方式處理HEAD(即,不發送任何正文),並發送錯誤響應不支持的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM