2009-12-18 232 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表示。