1.1TCP/IP网络模型
对于同一台设备上的进程通信,有很多种方式,比如有管道、消息队列、共享内存、信号等方式,而对于不同设备上进程的通信,就需要网络通信,而设备具有多样性,需要兼容各种各样的设备,就协商出了一套通用的网络协议。
【应用层】
最上层的,我们能直接接触到的就是应用层,电脑或手机使用的应用软件都是在应用层实现的。当两个不同的设备应用需要通信的时候,应用就把应用数据传给下一层,传输层。
应用层只需要专注于为用户提供应用功能,不用去关心数据是如何传输的。
应用层是工作在操作系统中的用户态,传输层及以下工作在内核态。
【传输层】
应用层的数据包会传给传输层,传输层是为应用层提供网络支持的。
传输层有两个传输协议,分别是TCP和UDP。
TCP的全称是传输层控制协议(Transmission Controller Protocol),大部分应用使用的都是TCP传输层协议,比如HTTP应用层协议。TCP相比于UDP多了很多特性,比如流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。
UDP就相对很简单,简单到只负责发送数据包,不保证数据报是否能抵达对方,但它实时性相对更好,传输效率更高。当然,UDP也可以实现可靠传输,把TCP的特性在应用层实现就可以了。
应用需要传输的数据可能会非常大,如果直接传输就不好控制,因此当传输层的数据包大小超过MSS(TCP最大报文段长度),就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新传这一个分块,不用重新发送整个数据报。在TCP协议中,每一个分块叫作一个TCP报文段。
当设备作为接收方时,传输层负责把数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据,因此需要一个编号将应用区分开来,这个编号就是端口。比如80端口通常是Web服务器用的,22端口通常是远程登录服务器用的。而对于浏览器中的每个标签栏都是一个独立的进程,操作系统会为这些进程分配临时的端口号。传输层的报文中会携带端口号,因此接收方可以识别出该报文是发送给哪个应用。
【网路层】
实际场景的网络环节是错综复杂的,中间有各种各样的线路和分叉路口。如果一个设备的数据要传输给另一个设备,就需要在各种各样的路径和节点进行选择,而传输层的设计理念就是简单、高效、专注。我们不希望传输层协议处理太多的事情,只需要服务好应用就行了,实际传输功能就交给网络层。
网络层最常使用的就是IP协议,IP协议会将传输层的报文作为数据部分,再加上IP报头组装成IP数据报,如果IP数据报大小超时MTU(以太网一般是1500字节)就会再次进行分片,得到一个即将发送到网络的IP报文。
网络层负责将数据从一个设备传输到另一个设备,网络层由区分设备的编号。我们一般用IP地址给设备进行编号,对于IPV4协议,IP地址共32位,分成了四段,每段是8位。网络号:负责标识该IP地址是属于哪个子网的;主机号:负责标识同一子网下的不同主机;配合子网掩码算出IP地址的网络号和主机号。在寻址的过程中,先匹配到相同的网络号,才会去找对应的主机。
除了寻址能力,IP协议还有另一个重要的能力就是路由。实际场景中,两台设备并不是用一条网线连接起来的,而是通过很多网关、路由器、交换机等众多网络设备连接起来的,那么就会形成很多条网络的路径,因此当数据报到达同一个网络节点,就需要通过算法决定下一步走 哪条路径。IP协议的寻址作用是告诉我们去往下一个目的地该走哪个方法,路由则是根据下一个目的地选择路径,寻址像是在导航,路由像是在操作方向盘。
【数据链路层】
实际场景中,网络并不是一个整体,所以数据不仅可以在同一个网络设备中进行传输,也可以跨网络传输。一旦数据需要跨网络传输,就需要有一个设备同时出现在两个网络当中,这个设备一般是路由器,路由器可以通过路由表计算出下一个要去的IP地址。于是就需要有一个专门的层来标识网络中的设备,让数据在一个链路中传输,这就是数据链路层,它主要为网络层提供链路级别传输的服务。
每一台设备的网卡都会有一个MAC地址,它是用来唯一标识设备的。路由器计算出了下一个目的地IP地址,再通过ARP协议找到该目的地的MAC地址,这样就知道这个IP地址是哪个设备的了。
【物理层】
当数据准备要从设备发送到网络时,需要把数据包转换成电信号,让其可以在物理介质中传输,这一层就是物理层,它主要是为数据链路层提供二进制传输的服务。
1.2键入网址到网页显示,期间发生了什么?
(1)浏览器做的第一步工作是解析URL,从而生成发送给Web服务器的请求信息。
对URL进行解析之后,浏览器确定了Web服务器、目录名和文件名,接下来就是根据这些信息生成HTTP请求信息了。
(2)DNS域名解析
通过浏览解析URL并生成HTTP消息后,需要委托操作系统将消息发送给Web服务器。但在发送之前,需要查询服务器域名对应的IP地址,因为委托操作系统发送消息时必须提供通信对象的IP地址。
DNS域名解析工作首先会从浏览器的缓存中查找,如果没有就向操作系统的缓存要,如果还没有就从本机域名解析文件hosts中查找,如果还是没有就会通过DNS服务器进行查询,通过根域名服务器->顶级域名服务器->权威域名服务器,完成整个DNS域名解析的过程,权威域名服务器会告知本机DNF服务器该域名是目标IP地址是多少,这样就完成了整个域名解析的动作。
(3)指南好帮手-协议栈
通过DNS获取到IP后,就可以把HTTP的传输工作交给操作系统中的协议栈。
应用程序(浏览器)通过调用Socket库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的TCP和UDP协议,他们俩会接收应用层的委托执行收发报文段的操作。协议栈的下半部分是IP协议,控制IP数据报的收发工作工作。在互联网上上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由IP负责的。
此外IP中还包括ICMP协议和ARP协议。ICMP协议是用于告知网络包传送过程中产生的错误以及各种控制信息;ARP用于根据IP地址查询相应的以太网MAC地址。
(4)可靠传输-TCP
源端口号和目标端口号是不可少的,如果没有这两个端口号,数据就不知道应该发给哪个应用。TCP传输数据之前,要先经过三次握手建立连接,保证双方都有收发数据的能力。
如果HTTP消息比较长,超过了MSS,TCP就需要把HTTP的数据拆分成一块块报文段进行发送,而不是一次性发送所有的数据。拆分出来的报文段,都会被放进单独的网络包中,在每个拆分的数据加上TCP头信息,在目的端口和源端口的字段填上端口号(Http默认端口号是80,Https的默认端口号是443),然后交给IP模块来发送数据。
(5)远程定位-IP
TCP模块在执行连接、收发、断开等各阶段操作时,都需要委托IP模块将数据封装成网络包发送给通信对象。
在IP协议里需要由源地址IP和目标地址IP:
源地址IP是客户端发出的IP地址;目标IP地址是DNS域名解析得到的Web服务器IP。
(6)两点传输-MAC
生成了IP头部以后,接下来网络包还需要在IP头部的前面加上MAC头部。MAC头部是以太网使用的头部,它包含了接收方和发送方MAC地址等信息。
在TCP/IP通信里,MAC头部的协议类型只使用:0800IP协议、0806ARP协议。
发送方的MAC地址获取就比较简单了,MAC地址是在网卡生产时写入到ROM里的,只要将这个值读取出来写入到MAC头部就可以了。
接收方的MAC地址就有点复杂了,只要只要告诉以太网对方的MAC地址,以太网就会帮我们把包发送过去。所以就需要使用到ARPC协议来获取目标IP的MAC地址。
ARP协议会在以太网中以广播的形式,对所有的设备喊出这个IP地址是谁的,请把你的MAC地址告诉我。然后就会有人回答,这个IP地址是我的,我的MAC地址是XXXX。如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到对方的MAC地址。然后,将这个MAC地址写入MAC头部,MAC头部就完成了。
在后续操作系统会把本次查询结果放到一块叫ARP缓存的内存空间留着以后用,不过缓存的时间就几分钟。
也就是说:先查询ARP缓存,如果其中已经保存了对方的MAC地址,就不需要发送ARP查询,直接使用ARP缓存中的地址;而当ARP缓存中不存在对方MAC地址时就需要发送ARP广播查询。
(7)出口-网卡
网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此我们需要将数字信息转换成电信号,才能在网线上进行传输,也就是说着才是真正的数据发送过程。负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。
网卡驱动从IP模块获取到包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列FCS。起始帧定界符是一个用来表示包起始位置的标记,末尾的FCS(帧检验序列)用来检查包传输过程是否有损坏。
最后网卡会将包转为电信号,通过网线发送出去。
(8)送别者-交换机
电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。然后通过包末尾的FCS检验错误,如果没问题则放到缓冲区。接下来需要查询一下这包的接收方MAC地址是否已经在MAC地址表中有记录了。
交换机的MAC地址表主要包含两个信息:1.设备的MAC地址;2.该设备连接在交换机的哪个端口; 端口与MAC地址将一一对应。如果接收方的MAC地址对应上交换机的MAC地址表中的信息,就可以得到对应的端口了。然后就可以将信号发送到相应的端口。如果没有对应的MAC地址,那交换机无法判断应该把包转发到那个端口,只能将包转发到除了源端口以外的所有端口上了。
(9)出境大门-路由器
网络包经过交换机到达路由器,并在此被转发到下一个路由器或目标设备。
【路由器的基本原理】
路由器的端口具有MAC地址,因此它能够成为以太网的发送方和接收方,同时还具有IP地址。
当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网网发送出去。
【路由器的包接收工作】
电信号到达网线接口部分,路由器中的模块会将电信号转换为数字信号,然后通过包末尾的FCS进行错误校验。如果没问题则检查MAC头部的接收方MAC地址,看看是不是发送给自己的,如果是就放到接收缓冲区中,否则就丢弃这个包。
【查询路由表确定端口】
完成包的接受操作以后,路由器就会去掉开头的MAC头部。MAC头部的作用就是将包送达路由器,其中的接收方MAC地址就是路由器端口的MAC地址。因此,当包到达路由器之后,MAC头部的工作就完成了,就会被丢弃。然后路由器根据IP头部的内容进行包的转发,根据包的接收方地址查询路由表中的目的地址栏,找到匹配的记录,转发到对应的接口。如果找不到匹配路由就会选择默认路由。
知道对方的IP地址之后,通过ARP协议根据IP地址查询MAC地址,再给网络包加上MAC地址头部和帧检验序列FCS。再转换成电信号发送出去。
(9)互相扒皮
数据包抵服务器后,服务器首先扒开数据包的MAC头部,查看是否与服务器自己的MAC地址符合。符合就将包收起来。接着继续扒数据包的IP头,发现IP地址符合,根据IP协议项知道上层是TCP协议。于是扒开TCP的头,里面有序列号,需要看看这个序列号是不是想要的,如果是就放入缓存中然后返回一个ACK,如果不是就丢弃。TCP头部里面还有端口号,HTTP的服务器正在监听这个端口号。于是服务器自然知道是HTTP进程想要这个包,就将包发给HTTP进程。
服务器的HTTP进程看到,这个请求要访问一个页面,就把这个网页封装在HTTP响应报文里。HTTP响应报文也要加上TCP、IP、MAC头部,不过这次的源地址是服务器IP地址,目的地址是客户端的IP地址。
最后到达客户端后,客户端把收到的数据包扒皮剩HTTP响应报文后,交给浏览器去渲染页面。
最后如果客户端要离开了,向服务器发起TCP四次挥手,双方连接断开。