尚在施工中,只完成了web server部分 : )
Web Server
Web Server 基本原理
当我们在浏览器浏览网页的时候,浏览器会先请求DNS Server,获得请求站点的IP Address,然后发送一个HTTP Request给该IP Address对应的主机,接着就会收到该地址回传的HTTP Response,而浏览器经过渲染后,将网页以一定形式呈现给我们。在此过程之中等待请求作出响应的主机,就是我们所说的Web Server。
更详细地看,Web Server是一台物理服务器上的一台网络服务器(也可以理解为一个程序),它二十四小时永久等待Client(浏览器或者任何使用HTTP协议的软件)发送请求,并在接受请求之后,生成相应的响应回传给Client。Web Server 和 Client之间使用的协议是HTTP,因此我们也将其称为HTTP Server。
Web Server能向Client提供文档,也可以放置网站文件、数据文件,供客户端浏览与下载。目前在UNIX和LINUX平台下最主流的Web Server是Apache和Nginx。

Web Server的工作原理可以分为四个步骤:建立连接、请求过程、应答过程以及关闭连接。
- 建立连接:Client通过TCP/IP协议建立到Server的TCP连接
- 请求过程:Client向Server发送HTTP协议请求包,请求服务器里的资源文档
- 应答过程:Server向Client发送HTTP协议的应答包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理动态内容,并将处理后的数据返回给客户端。客户端将揭示其HTML文档。
- 关闭连接:Client同Server断开连接。
虽然Web Server的主要工作是request和response,但实际中的web server会有更多的服务,比如:
- 缓存机制:将常访问页面缓存起来,提高响应速度
- 安全:防止黑客的各种攻击
- 并发处理:如何响应不同客户端同时发起的请求
- 日志:记录访问日志,方便做分析
Web Server 简单实现
我们可以一起来搭建一个简单的Web Server。
unsighed short serverPort = 8888;
int serverSocket;
int clientSocket;
struct sockaddr_in serverAddress;
struct sockaddr_in clientAddress;
if((serverSocket = socket(PF_INET, SOCK_STREAM, IPROTO_TCP)) < 0) {
die("socket failed");
}
// construct local address
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(serverPort);
if(bind(serverSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) < 0){
die("bind failed");
}
if(listen(serverSocket, MAXPENDING) < 0){
die("listen failed");
}
int clientLength = sizeof(clientAddress);
char buffer[4096];
if((clientSocket = accept(serverSocket, (struct sockaddr*) &clientAddress, &clientLength)) < 0){
die("accept failed");
}
if(recv(clientSocket, buffer, 4096, 0) < 0){
die("recv failed");
}
//analyze receive request
//create response
char response[some length] = {"HTTP/1.1 200 OK\n", "Hello, World!"}
size_t n = sizeof(response);
if(send(clientSocket, response, n, 0) != n){
die("chunk send fail");
}
close(clientSocket);
在terminal运行server后,我们可以通过http://localhost:8888/ 来访问页面(会显示一行“hello world”)。
Socket & HTTP
让我们再多来谈谈URL,下图是它的基本结构,它告诉了客户端需要连接的web server和以及到达后需要访问的服务的页面(路径)。

在客户端发送HTTP请求之前,它会与服务器建立一条TCP连接,然后通过该TCP连接发送一个HTTP Request并且收到HTTP Response。而建立TCP连接会使用Sockets,下图用了telnet指令来手动模拟该过程。

建立TCP Connection后,客户端将发送HTTP Request,下图是请求的基本结构。

HTTP请求包含一个Action(GET),Path(/hello)以及HTTP Version(HTTP/1.1)。
而服务器返回的HTTP Response的基本结构如下:

HTTP响应将包含一行Header,其包括了Version 与 Status Code,接下来空一行,然后是HTTP Response Body。