在前文中,我们对计算机网络的微观层面与宏观层面进行了简单的分析,发现:在进行软件层上的网络程序设计时,我们可以将网络数据的读写视作为对“远程文件"的读写。
扎根于这一基础之上,我们计划更加深入地对计算机网络开发进行讨论,以分层模型与客户端服务器模式进行切入。
分层模型
分层模型的本质,就是对“主机-主机"中的流程进行分解,下面,我们可以通过文字对这一完整的流程进行叙述,并最后将其总结为“分层模型"。
对于一名软件设计者而言,想要顺利地完成网络数据的读写,就必须确定如下的事务:
- 数据包的格式
- 主机间交换数据的方式
- 主机间定位的方式
网页读写就是一个好的案例,我们现在就可以开始分析他们。
应用层:简单的文本数据交换
在打开网页的时候,我们的浏览器往往会向对应的服务器发送一个数据包,作为请求数据
以启动我们信息管理实验室的首页为例,在启动网页以后,我们可以按下 F12 打开网络开发者工具(FireFox),看到网页浏览器的请求数据包。
将其中的重要信息进行提取,可以得到
GET / HTTP/1.1
它指出了需要进行的动作 ‘GET’(获取),要获取的对象为’/'(代表网站根目录,一般情况下就是网站的首页),而 HTTP/1.1 则是这一协议的名称与版本号,它是一个应用层协议,对于类似于上面这样的可读文本进行了相关的规定,确保我们的应用之间可以以一种合理的形式请求数据,发送数据。
这种以我们可以轻松阅读的文本格式所进行的数据收发,就是应用层所进行的操作,如你所见,比起复杂的电子信号传输,它非常简单,易懂。
我们大部分的开发,就是在应用层上进行的。
传输层:以合理的方式进行数据交接
在请求数据包填写完成之后,我们需要选择一种合理的方式,将我们的请求数据包发送到服务器上
数据包的收发读写,是两台不同主机之间的数据交换,因此,我们当然需要找到一种稳定的数据交换方式。
这就是传输层的工作,完成这份工作的协议分为 TCP 与 UDP 两种,对于我们的网页浏览工作而言,我们往往选择 TCP 协议。
网络层:定位我们的网络设备
在选择数据的传输方式之后,我们还需要正式定位目标服务器的地址,将我们的数据包传输过去
在这里,我们可以暂时切断我们的网络连接,并对我们网页浏览器发送的数据包进行查看。
可以很明确地发现,我们的请求数据包,协议等依旧保持不变,唯一的区别在于 ‘We can’t connect to the server’(我们无法连接到服务器)
从硬件上看,这是因为两台主机之间的数据链路没能建立,而在软件上看,错误在于:没能完成对目标主机的定位工作。
而当我们再次完成网络连接以后,我们可以继续顺利地连接网络,不过这一次,我们可以更换一种连接方式,选择 ping
这一次,出现了一个数字串 14.215.177.38,这被称为 “IP地址"(IPv4),它的实质是一个二进制数字串,代表了网络设备的地址
这种采用二进制数字串标识设备,确定连接地址的工作,就是网络层的工作,它需要来自于硬件的支持。
链路层与物理层:来自于硬件层面的支持
对于软件开发者而言,我们可以更多的对于这些硬件层面的协议保持一个 “知道有,不了解过多" 的态度,因为这些复杂的硬件层面事物,更多的由操作系统与硬件驱动为我们代劳,我们的精力,可以集中于应用层、传输层与网络层这些软件层上面的事物,并依托操作系统的系统调用(实际上就是一组设计良好的C语言函数)进行处理。
小结:分层模型与 OSI 参考模型
分层模型的正式模型是“TCP/IP 模型“,它是应用广泛的现实主义模型,而 OSI 模型是一个理论上的模型,我们可以把他们作一个简单的了解。
客户端服务器模式
许多的网络书籍喜欢将计算机网络数据的读写划分为“客户端服务器模型"与“P2P模型",而我本人则更加倾向于:两种模型没有本质上的区别,他们都是主机与主机之间的数据读写。
唯一的不同在于,哪一方主机预先发起了数据交换的请求。
案例:网页浏览
还是以网页浏览为案例,只不过,这一次,我们以“远程文件读写"的方式去看待。
我们欢迎你尝试如下的指令(假定你安装了 php 包,并且属于 Linux 操作系统)
mkdir website
cd website
echo "<h1>Hello world</h1>" > index.html
php -S 127.0.0.1:8000
在顺利得到如下的页面以后,我们可以在我们的 website 文件夹之中,创建一个新的网页文件(我将其命名为 new.html),并写上自己喜欢的内容。
再在浏览器里面输入,new.html
就可以得到新的内容。
分析:客户端服务器模式的良好体现
这个实验非常良好地体现出了我们的客户端服务器模式,一方面,我们可以看到,php 所提供的服务器服务,非常良好地进行着响应,在我们启动浏览器进行对应的数据请求的时候(如第一次,我们请求的网页路径就是 / ,也就是网站的首页文件 index.html),它将对应的文件很好地传输给我们,交付我们的浏览器进行解析,从而得到正确的结果;而另一方面,我们的浏览器也非常良好的起到了客户端的作用,它向我们的服务器发起请求,希望能够获取到对应的数据,事实上,它也获取到了(就是最后的网页文件)。
整个流程可以以下面的简化图进行看待:
可以看到,只需要完成彼此之间的连接,就可以进行数据的读写,而不再需要进行什么区分。
换而言之,我们就可以将客户端服务器模型视作一个“连接的先后问题",先发起连接的是客户端,接受连接的就是服务器。
小论:P2P 模型
很多网络书籍的“P2P模型",在我本人看来,就是客户端服务器模型的一个变种,并没有本质上的区别。
以我们常见的游戏服务器作为案例,在局域网中,总会有一个人作为搭建服务器的第一人,而其它连接进入这个服务器的人,又可以为其它的“弟兄们"提供对应的服务器服务,这就是一种“P2P",它让接入“服务器"的客户端,也成为网络服务的提供者。
而如果我们从文件读写的角度上面看,它并没有什么大不了的事情,只不过,我们受到了来自于“远程文件"的信息,从而也开始启动我们自己的网络服务了而已。
殊途同归,这就是我个人的评价。