2009-12-18 290 views
0

當客戶端向Web服務器發送請求時。 Web服務器是否打開一個新的套接字?或者是用於新請求的現有開放套接字?如果它爲每個新請求打開一個套接字,由於Http是無狀態協議,因此如何管理它。對於所有的Web服務器還是這樣,或者不同的Web服務器以不同的方式處理它們?Web服務器套接字

回答

7

使用Unix的術語(這是幾乎普遍 - 插座中的Unix BSD的味道引入,並從那裏到處宣揚),幾乎所有的TCP網絡服務器(web的或其他方式)將在綁定到「衆所周知的端口」(通常但不一定是HTTP服務器的端口80)的套接字上完成了listen。當客戶端connect時,服務器被通知(以依賴於操作系統的方式),然後它可以在偵聽套接字上執行accept,該套接字創建新的套接字。

根據所使用的HTTP協議(普通1.1,或舊的,但仍然使用1.0)的級別和請求中的一些頭文件,客戶端可能會要求使用一次性套接字(它只會處理一個請求和一個響應),或者更常見的是一個持久的(也被稱爲舊的術語,約定HTTP 1.0後期,作爲「保持連接」)。服務器不必遵守客戶端對連接的持久請求,但通常會嘗試,因爲它使客戶端性能變得更好。每個服務器可以肯定地選擇他們自己的啓發式方法,以瞭解它何時加載太多(同時進入的請求太多)以遵守持久連接的請求。

即使持續連接正在使用中,HTTP仍然是無狀態 - 客戶端可能會在仍然打開的套接字上發出不同的請求,並且/或者嘗試打開不同的套接字,而HTTP只是分別處理每個請求/響應對。套接字的持久性僅在TCP握手方面節省時間& c(因爲HTTP在TCP之上工作,每個新的TCP連接都需要自己的握手)。

0

基本答案:服務器將綁定到套接字,並將等待連接。這是無狀態的,因爲客戶端會打開許多​​單獨的連接,並且每個請求都可以獨立運行。

不完全確定各種網絡服務器如何處理它。

希望能以某種方式提供幫助。

0

一個套接字偵聽單個端口,並且所有請求都可能通過相同的端口來到Web服務器。因此(通常來說)有一個接受所有傳入請求的套接字,然後每個套接字都被傳遞給一個處理程序線程。通常這些處理程序線程被集中並重用,因爲繼續銷燬並創建它們非常昂貴。

編輯:我站好了。根據Alex Martelli的迴應,socket.accept()創建一個新的套接字。那麼談論持續連接就變得有效了。

這裏是一個不錯的例子(從http://devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=396),雖然這不使用線程池的:

import java.io.*; 
import java.net.*; 
import java.util.*; 

public final class WebServer { 
    public static void main(String args[]) throws Exception { 

     //Establish the listen socket 
     int PORT = 5306;  //select your favorite number > 1123 
     ServerSocket listenSocket = new ServerSocket(PORT); 

     //Process HTTP service requests in an infinite loop 
     while(true) { 
      //listen for TCP connection request 
      //Construct an object to process the HTTP request message 
      HttpRequest request = new HttpRequest(listenSocket.accept()); 
      Thread thread = new Thread(request); 
      thread.start(); 
     } 
    } 
} 

至於無國籍,像餅乾和會話用於從一個請求識別用戶到另一個。 Cookie是寫入客戶端的數據,每個請求發送到服務器,會話由可以放入URL或通過其他方式發送的ID表示。