一、网络编程 #
1. 客户端-服务器编程模型 #
每个网络应用都是基与客户端-服务器模型的。采用这个模型,一个应用是由一个服务器进程和一个或者多个客户端进程组成。 服务器管理某种资源,并且通过操作这种资源来为它的客户端提供某种服务。例如,一个 Web 服务器管理着一组磁盘文件,它会代表客户端进行检索和执行。
客户端-服务器模型中的基本操作是事务(transaction),一个客户端-服务器事务由以下四步组成:

2. 网络 #
客户端和服务器通常运行在不同的主机上,并且通过计算机网络的硬件和软件资源来通信。对主机而言,网络只是又一种 I/O 设备,是数据源和数据接收方,如图。

因特网客户端和服务器通过在连接上发送和接收字节流来通信。一个套接宇是连接的一个端点。每个套接字都有相应的套接字地址,是由一个因特网
地址和一个 16 位的整数端口组成的,用“地址:端口”来表示。一个连接是由它两端的套接字地址唯一确定的。这对套接字地址叫做套接字对(socket pair), 由下列元组来表示:(cliaddr: cliport, servaddr: servport)

套接字接口是一组函数,和Unix I/O结合起来用以创建网络应用。下图是典型的概述。

socket函数用来创建一个套接字描述符;客户端用connect建立和服务器的连接;服务器用bind来将套接字描述符和套接字地址练习起来,用listen将sockfd从一个主动套接字转化为一个监听套接字,可以接受来自客户端的连接请求,用accept等待来自客户端的连接请求。

二、Web基础 #
Web客户端和服务器之间的交互用的是一个基于文本的应用级协议,叫做HTTP(Hypertext Transfer Protocol,超文本传输协议)。一个Web客户端(也就是浏览器)打开一个到服务器的因特网连接,并请求某些内容;服务器响应所请求的内容,然后关闭连接;浏览器读取这些内容,并把它显示在浏览器上。
1. Web内容 #
对于Web客户端和服务器而言,内容是与一个 MIME(Multipurpose Internet Mail Extensions)类型相关的字节序列,下面是常用的MIME类型:
| MIME类型 | 描述 |
|---|---|
text/html |
HTML页面 |
text/plain |
无格式文本 |
image/gif |
GIF格式编码的二进制图像 |
Web服务器可以以两种方式向客户端返回内容:
- 取一个磁盘文件,并将内容返回给客户端,磁盘文件称为静态内容,返回的过程称为服务静态内容。
- 运行一个可执行文件,并将结果返回给客户端,可执行文件产生的输出称为动态内容,返回的过程称为服务动态内容。
每条由Web服务器返回的内容都是和它管理的某个文件关联,这些文件有唯一的名字,叫做URL(Universal Resource Locator)。确定一个URL指向的是静态内容还是动态内容没有标准,每个服务器有自己的规则。例如,确定一组目录cgi-bin,所有的可执行文件都必须存放在这些目录中。最小的URL后缀是/字符,所有服务器将其扩展为某个默认的主页例如/index.html。
2. HTTP事务与报文 #
为了发起HTTP事务,客户端会发送一个HTTP请求报文,服务器返回HTTP响应报文,然后关闭连接。每种报文必须按照特有格式才能被浏览器识别。浏览器发送的是请求报文;返回的是响应报文。
- HTTP请求报文
HTTP请求报文由一个请求行(request line)、零个或更多个请求头部(header)、一个空行、请求数据四个部分组成。其中GET请求中请求数据部分为空。
这是一个GET方法的请求报文例子:
GET / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 Edg/148.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
空行
请求数据为空请求行的格式是method URI version,例如GET / HTTP/1.1。
请求头部提供了额外的信息,格式是header-name: header-data,例如Content-Type:application/x-www-form-urlencoded说明媒体类型。
空行用来终止头部列表。在POST方法中会有请求数据部分,可以添加其他数据。
- HTTP响应报文
HTTP响应也由四个部分组成,分别是:一个响应行、零个或更多个消息报头、一个空行和一个响应正文。
这是一个响应报文例子:
HTTP/1.1 404 Not Found
Content-Type: text/html
Content-Length: 48
空行
<html><body><h1>404 Not Found</h1></body></html>响应行的格式是version status-code status-message。状态码是一个3位的正整数,指明对请求的处理,如200是成功,404是服务器找不到所请求的文件。
3. 服务动态内容 #
CGI(Common Gateway Interface)的实现标准可以帮助服务器服务动态内容。
首先,GET请求的参数在URI中传递,?分割文件名和参数,每个参数用&分隔开。POST请求的参数在请求主体中。当服务器接收到一个请求:
GET /cgi-bin/adder?15000&213 HTTP/1.1 它会调用fork和execve来在子进程上下文中执行cgi-bin/adder,adder这种程序称为CGI程序,在execve之前,子进程将CGI环境变量QUERY_STRING设置为15000&213,从而CGI程序运行时可以用getenv函数引用它。CGI定义了大量的环境变量,在运行时可以设置。
CGI程序将动态内容发送到标准输出。不过,子进程加载和运行CGI之前用dup2将标准输出重定向到和客户端相关联的已连接描述符,这样输出就直接到达客户端了。同样对于POST请求,子进程将标准输入重定向到服务器,方便读取参数。