在数据收发层面,不需要区分客户端和服务器。连接操作上需要区分:发起连接的是客户端,等待连接的是服务器。
服务器和客户端的网络相关的组件是相同的,但用法不同。
服务器可以与多台客户端通信,它的程序结构和客户端也不同。
服务器程序分为等待连接模块和与客户端通信的模块。程序启动并完成初始化后,就运行等待连接模块,创建套接字后进入等待连接的暂停状态。
客户端发起连接时,该模块恢复运行,并接受连接,启动客户端通信模块,并移交完成连接的套接字。
客户端通信模块使用已连接的套接字和客户端进行通信。通信结束后,通信模块会退出。
每次有新的客户端发起连接,都会启动一个新的客户端通信模块,与客户端是一对一的关系。
accept接受到客户端的包时,协议栈会给等待连接的套接字复制一个副本,并把连接对象等控制信息写到新的套接字中。这时等待连接模块会启动客户端通信模块,并将套接字副本会转交给客户端通信模块。
复制出套接字副本后,原先的套接字仍然处于等待连接状态。新的客户端的包到达时,它又会执行接受连接操作,再次复制一个套接字副本。
IP头部和TCP头部包含了4项信息:接收方IP、接收方端口号、发送方IP、发送方端口号。通过这4项信息就能确定某个套接字。
TCP模块发现TCP头部控制位的SYN为1时,说明是一个发起连接的包。
请求消息中包括请求方法和表示数据源的URI,服务器程序根据这些信息向客户端返回数据。
Web服务器公开的目录不是磁盘上的实际目录,而是虚拟目录。URI中写的就是在虚拟目录结构下的路径名。在读取文件时,需要先查询虚拟目录与实际目录的对应关系,并将URI转换成实际的文件名,才能读取并返回数据。
URI中省略文件名时,服务器会读取预先设定好的默认文件名。
可以设置文件名改写规则,在URI中的路径符合改写规则时,将URI中的文件名改写为其他文件名进行访问。这在服务器的目录和文件发生变化并且需要用户通过原来的网址访问时很有用。
URI指定的文件内容不一定是HTML文档,也可能时一个程序。这时服务器会运行这个程序,然后将程序的输出返回给客户端。
浏览器将需要服务器程序处理的数据放在HTTP请求消息中发送给服务器。数据加在HTTP消息中的两种方法,一是通过GET方法,把输入的数据作为参数添加在URI后面;二是通过POST方法,把数据放在HTTP请求体中发送给服务器。
收到请求消息后,Web服务器检查URI指定的文件名是不是程序。如果是程序,Web服务器会委托操作系统运行这个程序,然后从请求消息中取出数据交给该程序。
程序处理后,输出结果一般会嵌入HTML中。Web服务器将其作为响应消息返回给客户端。
访问控制可以根据预先设定的规则,允许或禁止访问。
收到请求时,服务器根据URI判断数据源,并检查数据源对应的访问控制规则,只有允许访问时才读取文件或运行程序。
接受连接时就能知道客户端的IP地址,可以检查是否允许访问。
先根据IP地址向DNS服务器查询客户端域名,然后再用该域名查询一下IP地址,看结果是否和发送方IP一致。如果一致则检查对应的访问控制规则。
这种方式需要和DNS服务器做多次查询,会使Web服务器响应速度变慢。
有一种在DNS服务器上注册假域名的攻击方式,因此需要双重检查。
收到需要用户名和密码的访问时,Web服务器会向客户端发送一条响应消息,告诉用户需要在请求消息中放入用户名和密码。
浏览器收到该消息,会弹出输入用户名和密码的窗口,用户输入用户名和密码后,浏览器把这些消息放入请求消息中重新发给服务器。
服务器检查收到的用户名和密码,与注册的信息一致时,才返回数据。
Web服务器调用write,把响应消息交给协议栈,告诉协议栈这个消息对应的套接字。
协议栈会把数据拆分为多个包,加上头部发出去。
Web可以处理很多类型的数据,每种类型的显示方法都不同。
可以根据响应消息的头部字段Content-Type判断数据类型。
Content-Type: 主类型/子类型; charset=utf-8 Content-Type定义的数据类型:
| 主类型 | 含义 | 子类型 |
|---|---|---|
| text | 文本数据 | html,HTML文档; plain,纯文本; |
| image | 图像数据 | jpeg,JPEG格式图片; gif,GIF格式图片; |
| audio | 音频数据 | mpeg,MP2、MP3格式的音频; |
| video | 视频数据 | mpeg,MPEG格式的视频; quicktime,Quicktime格式的视频; |
| model | 对物体的形状和动作进行建模的数据 | vrml,VRML格式的建模数据; |
| application | 应用程序数据 | pdf,PDF文档数据; msword,MS-WORD格式的文档数据; |
| message | 直接存放邮件等消息时使用的类型 | rfc822,一般的邮件数据,包含From、Date等头部数据; |
| multipart | 消息体中包含多个部分的数据 | mixed,消息体中包含不同格式的数据,其中每部分数据都有单独定义的媒体类型; |
当数据类型为文本时,需要用charset附加文本的编码信息。utf-8表示Unicode,euc-jp表示EUC编码,ISO-022-jp表示JIS编码,shift_jis表示JIS编码。
如果消息的内容是通过压缩或编码技术转换过的,还需要检查Content-Encoding字段,得知如何将消息中的数据还原为原始数据。
HTML文档按照标签表示文档的布局和字体等样式信息。浏览器解释这些标签,并按照指定的样式显示文档内容。
HTML文档中有表示图片和视频的标签。浏览器遇到这些标签时,会向服务器请求其中的图片或视频数据。Web服务器返回数据后,浏览器解压该数据,然后委托操作系统显示。
Web服务器还会返回一些应用程序的数据,浏览器会调用相应的程序,或者是自身的插件。不同类型的数据和不同程序的对应关系在浏览器中已经设置好了。
显示操作实际上是操作系统完成的,浏览器负责对系统发出指令。