计算机网络 一:客户端的应用层

计算机网络分为应用层,运输层,网络层,数据链路层,物理层.
我们从客户端的应用层(也就是我们的日常应用)讲起,一层一层向下处理我们在应用程序里填写的数据,直到从客户端的物理层发送给服务器,再从服务器的物理层接受到这些数据开始,一层一层处理这些数据,再将数据转化成服务器应用程序能够理解的数据内容.

人们在1.输入网址,或者2.在网站填写一些数据并点击发送按钮时,就会触发计算机网络的数据传输.
数据传输的过程在http协议这方面看,就是http协议根据用户请求向下发送一段请求消息,请求消息中包含(方法,URI).
方法主要有Get和Post两种
在这里插入图片描述
在这里插入图片描述
URI在请求消息中指定的服务器中的一些.cgi,.php程序,或者是一些网页,图片之类的文件.
也就是我们的网址.

1.网址由协议机制(http),Web服务器名域名(www.csdn.net),文件名(index.html)这几个部分组成.输入网址(我们点击超链接的过程也相当于在浏览器中输入了一段网址)后,http一般会形成GET方法和一个网页文件为URI的请求消息.
2.网页中的表单源码会记录使用哪些方法,和使用哪个程序来处理.在点击表单中相应的按钮,就会触发向服务器发送请求消息的过程.

请求消息的格式:
在这里插入图片描述
第一行就包括了方法和URI.
<消息头>则记录了请求的附加信息(http主要的消息头可以百度得到,这里只解释大概存储了什么东西),如一些格式要求Accept-Language: 浏览器支持的语言,Host:域名,Connection:连接类型
而上传的表单数据就存放于<消息体>中.
如我们在表单中填入
在这里插入图片描述
如果网页的源码(网页源码就是html文件里的内容,可想而知,这个是存储在我们的电脑里的,我们是可以查看的)是这样的话
在这里插入图片描述
那么消息体里就会有这样的数据
在这里插入图片描述
从这张图我们就可以看出来,Get和Post的不同了.通过Get发送的数据是记录在消息信息的URI里的,所以消息体是空的,而POST则是存储在消息体里的.所以GET发送的数据不能太大,但实际上也能有几百字节之多了(如果要发送图片的话基本肯定是需要用POST了).

这个请求消息实际上还需要客户端其他几层的处理,但是再经过层层处理达到服务器的应用层时,服务器程序所看到的也是大致一模一样的请求消息内容.

以上的内容就是浏览器根据http协议生成的报文的过程了.

浏览器生成了报文以后,需要依靠操作系统将报文发送给服务器端,就像系统调用一样.那么这个委托操作之前呢,我们还必须要将url的服务器域名转换成它的IP地址.因为操作系统是不认识服务器域名的.所以我们需要先想办法找到服务器的IP地址.(服务器的IP地址就像是一个门牌号一样,全世界的服务器的IP地址都是不同的.)

下面先简单介绍一下ip地址,其实这个东西我们在计算机中已经见过很多了吧.
我们在使用电脑时见到的这个32比特,按8比特为一组的分为4组的,分别用十进制表示然后再用圆点分割的就是所谓的IP地址了.
在这里插入图片描述
当然我们也还常常见识到这种形式的IP地址
在这里插入图片描述
在这里插入图片描述

实际上/后面的就是IP地址的子网掩码,子网掩码的作用就是用来表示IP地址哪一部分是网络号哪一部分是主机号
在这里插入图片描述
那什么是网络号什么是主机号呢?大体的说计算机网络是由很多很多的小网络组成的,也就是局域网(以太网).网络号就是代表了去找计算机网络中哪个局域网(以太网).而主机号则是代表了去找局域网中的哪一台主机.
但是要提一点的是,没有哪个主机的主机号是0或者255的,如果是0的意思就是这个IP号代表的就是这一整个局域网,如果是255的话就表示向这个局域网中的所有主机发送包.

那么浏览器是如何将我们输入的网址制作成ip传给操作系统的呢?其实依靠的就是DNS(域名解析系统).浏览器会向DNS服务器发送一段查询消息,DNS服务器的响应消息中就有网址对应的ip地址.
那么具体是怎么做的呢?

浏览器等这些会联网的应用程序中会使用到一个叫做DNS解析器的程序.有C语言编程基础的,就会明白,编程时我们会调用C库里的程序,比如printf之类的,这里的DNS解析器也是相当于printf一样的一个函数.
在这里插入图片描述就像这样.我们调用了这个函数,这个函数接收一个网址,会返回一个ip地址.但是这个函数究竟是怎么工作的呢?
在这里插入图片描述其实这个C库函数中还会进行系统调用,如上.
但是这里有个很让人疑问的地方,那就是计算机访问Web服务器的时候是需要知道Web服务器的ip地址的,那么访问DNS服务器肯定也需要知道DNS服务器的地址啊,那计算机是怎么知道这个ip地址的呢?
其实这个DNS服务器的ip地址已经是事先存储好了的.我们打开这个界面就可以查看到我们电脑存储的一般会访问的DNS服务器的ip地址了.
在这里插入图片描述
DNS服务器实际上是有很多的,访问方式实际上是如图所示这样的.
在这里插入图片描述DNS服务器从大到小分为了很多的域,如glasscom.com域的DNS服务器的ip地址是存在Com域的DNS服务器中的.所以大域的DNS服务器中是存储着小域服务器的ip地址的.所以大域DNS服务器可以找到并且访问小域DNS服务器.但是观察图片会发现,最近的DNS服务器是可以直接访问根域的DNS服务器的.这是怎么做到的呢?其实由于根域是最大的域,所以不会存在太多的根域,世界上只有13个根域,13个根域这么少的信息直接可以存储在DNS服务程序中.

客户端通过将查询信息发送给最近的DNS服务器,最近的DNS服务器又再访问根域DNS服务器,根域再一层一层往下,找到最小域的DNS服务器,这个DNS服务器中就存储了我们所要查询的Web服务器的ip地址了.

通过DNS服务器获得了Web服务器的ip地址之后,那我们就可以把修改好的报文发给协议栈(也就是tcp/ip传输层和网络层)。那么浏览器是如何把修改好的报文下发给协议栈的呢?其实我们这里的发送说法是逻辑上的。实际上,就像我们程序设计中的结构一样,我们设置了底层数据库增删查改的基础函数,然后再在业务逻辑层上设计处理数据库增删查改产生的包装好的数据的处理函数。那么这里的协议栈就像业务逻辑层一样,而业务逻辑层处理数据库访问层中产生的数据,像是协议栈处理应用层产生的报文一样。只是我们平常程序设计的最终目的是给普通人能够直接使用,而现在的目的是将应用程序产生的数据可以在网路上传输。所以感觉上像是反了一样。还有一点不同的是,我们的业务逻辑层是通过调用数据库访问层来主动访问下层的,但是协议栈是应用程序调用Socket库中库函数,将数据作为参数传输给协议栈,所以协议栈是被动获取数据的。

了解计算机系统的应该明白,使用Socket库(也就是C库中的一个库),跟系统调用还是有区别的。不如说,C库的库函数有作系统调用的操作。这么看来,协议栈既然是属于系统的功能,而应用程序只是通过Socket库委托协议栈工作,那么Socket库也可以算在应用层的范畴里了,我们同样可以绕过Socket库直接进行系统调用协议栈,毕竟网络出现还是要比C语言要早的。但是我想,java这些语言的底层既然是通过C来做的,那么它们访问网络恐怕最终的最终还是得由Socket库来实现的吧。

好了,这里总结一下,Web应用程序中都做了什么事情呢?当然这里是以TCP形式的连接为例。UDP是不需要连接的。

首先Web应用程序会通过一Socket库的gethostbyname()函数来从DNS服务器上获取ip,然后就可以制作成最终的报文。
制作成报文之后,使用Socket库中的socket()函数,建立网络连接的端口(也就是套接字,有点玄,但是会在传输层中解释什么叫套接字,个人认为这个端口应该是属于传输层的范畴,应用程序所看到的就是一个网络连接的描述符)。
应用程序有了自己的端口,那么就可以通过Socket库中connect()函数连接服务器上的端口了。
连接完成之后就按照需求使用Socket库的Write(),Read()函数,发送请求的报文和读取响应的报文了。但是我们会注意到Write和Read并没有将什么数据返回给应用程序。其实底层中,Write和Read只是将数据从协议栈中拿出来,放到应用程序的缓冲区中,那么处理这块缓冲区的数据的方法就很多了。计算机网络的功能就到此为之。
最后就是调用Socket库中的Close()函数,来删除本机的端口。
如图所示
在这里插入图片描述
这就是应用层所完成的功能了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值