1.HTTP域名解析
浏览器做到第一步就是域名解析,解析完后会生成发送给Web服务器的请求信息。
有很多域名后面都会跟长长的url(如下图),这个url其实就是请求服务器中的文件资源,通过访问这个文件,大部分这个文件就是首页展示的静态页面,也就是.html文件。有些域名后面没有跟url的(比如百度),这些是在根目录中事先放了默认文件,也就是/indx.html或者/default。解析完域名后,就知道了Web服务器和文件名,接下来就可以生成HTTP请求了。
2.DNS真实域名查询
浏览器解析完url后生成HTTP消息后,委托操作系统将请求信息发给Web服务器,但是在这之前需要先查询服务器域名对应的IP地址。
IP地址就需要去DNS服务器去拿,DNS服务器用于专门存放web服务器域名和IP地址的对应关系。
DNS域名服务器的结构是类似于树状的结构,就像我们的快递地址,省市区街道,逐层精确,DNS域名服务器也是这样的,举个栗子,“www.hello.com”的实际域名是要在后面添加一个“.”,也就是“www.hello.com.”,那“.”就是根DNS服务器,“.com”是顶级域DNS服务器,“service.com”是权威DNS服务器,这样逐层寻找,就能找到对应Web服务器的IP地址了。
3.HTTP的传输:协议栈
通过DNS获取到IP地址后,就要请求Web服务器了,过程中的HTTP的传输工作就交给了操作系统的协议栈了,协议栈的结构是这样的:
协议栈有很多层,上层委托任务,下层执行任务。
首先应用程序会调用socket库来委托协议栈工作,协议栈的上半部分就是上篇文章讲的负责收发数据的TCP和UDP协议了,主要是接受应用层的委托去收发数据,下半部分是控制网络包收发操作的IP协议(数据在互联网中的发送是要把数据分割成多个网络包的),其中IP协议中还包括了ICMP协议和ARP协议,ICMP协议负责显示网络包传输过程中的报错信息和各种控制信息,ARP协议是来根据IP地址查询MAC地址。
网卡驱动程序和网卡硬件就是实际在网线中完成收发的操作。
4.协议栈的上半部分:TCP协议
上面说了,浏览器在解析完域名后,知道了Web服务器和文件资源,然后通过DNS服务器逐层找到了Web服务器的IP地址,然后浏览器就会调用socket库去委托协议栈去传输数据给web服务器,协议栈的上半部分就是TCP协议,TCP报文头部的格式如下:
首先需要知道一点,TCP和UDP不同,TCP是需要保持连接的,不能断连。
源端口号和目的端口号是为了知道数据发给哪个应用。
序号是为空解决数据包乱序的问题。
确认号是为了确认对方是否收到,防止丢包。
ACK这些是状态位,SYN是发起一个连接,ACK是回复,RST是重连,FIN是断连。TCP为了维护连接才有了这些状态位,一个有状态位的包会引起双方状态的变更。
窗口大小一是为流量控制,流量不能过快不能过慢,二是为了拥塞控制,尽量避免堵车。
HTTP在传输数据之前要建立TCP连接,也就是三次握手,这个连接可以理解为通过维护状态来保证双方都有发送和接收的能力。
时序图如下:
可以看到一个有状态位的包会引起双方状态的变更,在双方都接受到看ACK后,双方状态都从CLOSE变成了ESTABLISHED,这样连接就建立成功了。
在Linux中通过netstat -napt可以查看TCP连接的状态,如下图:
TCP切割数据:如果HTTP数据过长,超过了MSS(上篇文章讲过)的长度,就会把数据拆开成一个个数据块,一个个去发送,每个数据块前会加上刚刚讲的TCP头部和IP头部,然后去发送数据,如下图:
所以,这时一个网络包的报文就是TCP头部+数据块,其中数据块就是HTTP头部+消息体。
5.协议栈的下半部分:IP协议
因为IP协议是负责网络包的操作的,所以TCP在进行连接、断开等操作时都需要委托IP协议将数据封装成网络包发送给通信对象。
在IP协议的结构中,有几个需要注意的点:IP协议里需要有源地址IP和目标地址IP,其中源地址IP就是客户端输出的IP,目标地址IP是指DNS域名解析得到的web服务器IP。
这里要讨论一个问题:如果客户端有多个网卡时,该选择哪个网卡的IP地址作为源IP地址呢?
这个时候就需要路由表来决定源IP地址,Linux系统中,可以通过route -n来查看当前系统的路由表。如图所示:
路由表规则:需要通过目标IP和子网掩码进行与运算算出来源地址。比如我的目标地址是192.168.3.5,那我分别与路由表中的子网掩码(比如255.255.255.255)进行与运算,得到的IP(100.100.2.136)与Destination(100.100.2.136)对比,相同则选择这个源地址,相应的网卡是eth0。但如果都不匹配,则选择第一个默认网关,一般默认网关的IP地址和子网掩码是0.0.0.0。
此时网络包结构:
6.MAC地址:精确查找到是哪台设备
明确一点,后面会讲:发送网络包时,MAC头部的作用就是将网络包送达路由器。
我主页的上篇文章(基础篇1)中讲过,IP地址只能找到服务器对应的局域网,但是如果局域网中不止一台设备,那么就需要MAC地址来找到具体是哪台设备,MAC地址就是设备的身份证,也可以说是网卡的身份证,设备出厂就终生携带一个自己的MAC地址。
每个网络包前面都要添加上MAC头部,MAC头部有三部分,接收方MAC地址、发送方MAC地址、协议类型,这里的协议类型一般有两种:IP协议(0800)和ARP协议(0806),这里的ARP协议刚刚讲过它的作用是通过IP地址获取MAC地址。
这里的ARP协议是在同一局域网中,通过广播的形式,询问局域网中的所有设备,问这个IP地址是谁的,对应设备会说这个IP是我的,我的MAC地址是xxx,然后把这个MAC地址写入到MAC头部。
但是ARP协议每次都广播很麻烦,所有就有了ARP缓存的概念,每次ARP要查询MAC地址时,先去ARP缓存中看看有没有对应的MAC地址,如果有了就不需要广播了。在Linux中可以通过arp -a来查询ARP缓存的内容。如图:
现在网络包的结构就多了一个MAC头部,如图:
7.网卡:发送网络包的最后一道工序
网卡就是刚刚在协议栈中讲到的,将网络包转化成电信号的形式,以便在网线中传输,因为网络包其实也就是一段二进制数字信息,如下图:
执行收发操作的是网卡,但是控制网卡的是网卡驱动,网卡驱动会将网络包复制到网卡的缓存区,并在网络包头加上报头和起始帧分界符,末尾加上帧校验序列(FCS)用于检测错误,然后就转成电信号通过网线发出去了。
这里我简单总结一下网络包生成并发送的过程:键入网址后,首先浏览器会解析域名,如果域名有url的话就拿到url下的文件资源,没有url的话就拿根目录下的默认文件,然后去通过DNS域名解析服务器知道Web服务器的IP地址,这个时候知道了web服务器的IP地址和文件资源,就可以发送一个HTTP请求信息了,这个请求信息组成是HTTP头部+消息体,接着浏览器会调用socket库去委托协议栈中的上半部分TCP协议来进行传输步骤的第一步,TCP协议是在HTTP报文前面加上TCP头部,TCP头部中有源端口和目标端口,接着TCP协议委托协议栈的下半部分IP协议进行数据传输的第二步,IP协议会将数据封装成网络包,也就是加上IP头部,IP头部有源IP地址和目标IP地址,如果客户端有多个网卡也就是多个IP地址,就需要路由表来选择用哪个IP来当作源IP,让填入IP头部中,然后在数据包前再拼接上MAC头部就可以找到同一局域网下的对应那台服务器,最后再通过网卡将网络包转化成电信号通过网线发送给路由器。
8.交换机:将交换机原样转发到目的地
交换机工作在MAC层,也叫二层网络设备。
交换机将接收网线中的电信号数据,转化为数据信号,也就是二进制数字信息,检验包末尾的FCS校验错误,没问题就放进缓冲区。
与网卡接收网络包时的操作有些类似,网卡本身有自己的MAC地址,拿到目标MAC地址后和自己的MAC地址进行核对,看是不是发给自己的,不同则丢弃,但是交换机与网卡工作方式不同,交换机没有自己的MAC地址,它是通过MAC地址表来把网络包传到下一级。
交换机自己有一个MAC地址与网线端口映射表,作用是通过数据包中的MAC地址为数据包找到对应的网线端口。如果在这个表中找不到MAC地址对应的端口,那交换机就会通过广播的方式,把每个端口都复制并发送一个网络包,正确的端口会返回一个响应包,不正确的端口就会忽略这个网络包,并把这个MAC地址和对应的端口信息记录在MAC地址表中,下次再来就不用广播了。
还有一种情况就是接收方的MAC地址就是一个广播地址,这时交换机就会网络包发送给除源端口外的其他所有端口中。MAC地址中的广播地址:FF:FF:FF:FF:FF:FF,IP地址中的广播地址:255.255.255.255。
9.路由器:数据包发送到以太网的最后一道门
路由器是基于IP进行设计的,又叫三层网络设备,和交换机不同的是,交换机的端口没有MAC地址,但是路由器每个端口都有自己的MAC地址和IP地址,所以它可以成为以太网的接收方和发送方,从这个角度来说,它和网卡是一样的。
网络包由交换机通过网线传到路由器,路由器再转发到下一个路由器或者目标设备,这就是访问到目标设备的全过程。
首先路由器的模块会将电信号转化成数字信号,通过末尾的FCS进行错误校验,没问题的话检查网络包的MAC头部看是不是发给自己的,是的话就放进缓冲区,不是的话就丢弃。
前面说过,MAC头部的作用就是将网络包送达路由器,所以通过MAC头部确定这个网络包是发给自己的之后就可以把网络包的MAC头部丢弃了,然后通过IP头部进行转发操作。路由器和交换机很像,路由器有一张路由表(与交换机的MAC地址表结构一样,上面有图可以搂一眼),也是通过IP和子网掩码与运算后进行比较,从而确定转发目标,然后进行转发。这里包发送时要根据路由表中的网关列进行判断对方的地址,如果网关列是一个IP地址,说明还没到终点,还需要再进行路由器转发,但如果网关列为空,那网络包的IP地址就是目标地址,也就是终于到达终点了。第一种情况时,拿到IP地址后通过ARP协议拿到MAC地址,这个MAC地址就是接收方的MAC地址,也就是下一个路由器的地址,然后就将网络包转化为电信号通过网线传输到下一个路由器,层层转发,最后当网关列为空时,就到达了目的地!
这里有个现象就是,从头到尾网络包中的源IP和目标IP是一直不会变化的,一直变化的是MAC地址,因为MAC地址是负责在以太网中进行设备到设备中的传递。
服务器在拿到网络包后会逐层拨开,通过MAC地址和IP地址判断是不是给自己的,是的话就返回一个ACK,这个状态位刚刚有说过(其实TCP连接的每次握手都是一个网络包的发送),然后服务器将响应包给客户端,然后客户端交给浏览器渲染就得到了页面,最后进行四次挥手断开连接。
标签:网卡,IP,学习心得,地址,键入,计算机网络,MAC,IP地址,服务器 From: https://blog.csdn.net/wx_0311/article/details/142661416