TCP/IP 网络通常是由上到下分成 4 层,分别是应用层,传输层,网络层和网络接口层。应用层(Application Layer),我们电脑或手机使用的应用软件都是在应用层实现。那么,当两个不同设备的应用需要通信的时候,应用就把应用数据传给下一层,也就是传输层。应用层只需要专注于为用户提供应用功能,比如 HTTP、FTP、Telnet、DNS、SMTP等。应用层是不用去关心数据是如何传输的。
传输层(Transport Layer)是为应用层提供网络支持的。在传输层会有两个传输协议,分别是 TCP 和 UDP。
实际的传输功能就交给下一层,也就是网络层(Internet Layer)。负责将数据从一个设备传输到另一个设备。网络层最常使用的是 IP 协议(Internet Protocol)。
生成了 IP 头部之后,接下来要交给网络接口层(Link Layer)在 IP 头部的前面加上 MAC 头部,并封装成数据帧(Data frame)发送到网络上。网络接口层主要为网络层提供「链路级别」传输的服务,负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标识网络上的设备。

1.首先浏览器做的第一步工作就是要对 URL 进行解析,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。
2.DNS解析查询服务器域名对应的 IP 地址(目的地)。浏览器会先看自身有没有对这个域名的缓存,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去 路由器缓存看,也没有,才会去问「本地 DNS 服务器」。
3. 浏览器得到了IP以后,接下来向服务器发送TCP连接,TCP连接要先经过三次握手。三次握手目的是保证双方都有发送和接收的能力。在双方建立了连接后,TCP 报文中的数据部分就是存放 HTTP 头部 + 数据,组装好 TCP 报文之后,就需交给下面的网络层处理。
4.TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。加上了 IP 头部的数据包,有了远程定位的能力。
5.生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部。MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息。MAC 包用于两点之间的传输。
6.出口:网卡。网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。最后网卡会将包转为电信号,通过网线发送出去。
起始帧分界符是一个用来表示包起始位置的标记
末尾的
FCS(帧校验序列)用来检查包传输过程是否有损坏
7.送别者:交换机。电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。然后通过包末尾的 FCS 校验错误,如果没问题则放到缓冲区。交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口。
8.出境大门:路由器。网络包经过交换机之后,现在到达了路由器,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。
完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。
接下来,路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。
在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。
9.数据包抵达了服务器,服务器于是开始扒数据包的皮。服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。
接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP头部里面还有端口号, HTTP 的服务器正在监听这个端口号。
于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。
服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是服务器 IP 地址,目的地址是客户端 IP 地址。
穿好头部衣服后,从网卡出去,交由交换机转发到出城的路由器,路由器就把响应数据包发到了下一个路由器,就这样跳啊跳。
最后跳到了客户端的城门把守的路由器,路由器扒开 IP 头部发现是要找城内的人,于是又把包发给了城内的交换机,再由交换机转发到客户端。客户端收到了服务器的响应数据包后,同样也非常的高兴,客户能拆快递了!于是,客户端开始扒皮,把收到的数据包的皮扒剩 HTTP 响应报文后,交给浏览器去渲染页面,一份特别的数据包快递,就这样显示出来了!
最后,客户端要离开了,向服务器发起了 TCP 四次挥手,至此双方的连接就断开了。

DNS 服务器我们打电话的时候,必须要知道对方的电话号码,但由于电话号码难以记忆,所以通常我们会将对方电话号 + 姓名保存在通讯录里。
所以,有一种服务器就专门保存了 Web 服务器域名与 IP 的对应关系,它就是 DNS 服务器。
例如"mp3.baidu.com",域名先是解析出这是个.com的域名,然后跑到管理.com域的服务器上进行进一步查询,然后是.baidu,最后是mp3, 所以域名结构为:三级域名.二级域名.一级域名。
所以DNS根据域名查询IP地址的过程为:浏览器缓存 --> 操作系统缓存 --> 路由器缓存-->本地(ISP)域名服务器缓存 --> 根域名服务器。
特点:只指路不带路(本地域名服务器指向根DNS,指向com顶级域名..)
当设备作为接收方时,传输层则要负责把数据包传给应用,但是一台设备上可能会有很多应用在接收或者传输数据,因此需要用一个编号将应用区分开来,这个编号就是端口。
比如 80 端口通常是 Web 服务器用的,22 端口通常是远程登录服务器用的。而对于浏览器(客户端)中的每个标签栏都是一个独立的进程,操作系统会为这些进程分配临时的端口号。
由于传输层的报文中会携带端口号,因此接收方可以识别出该报文是发送给哪个应用
TCP 的全称叫传输控制协议(Transmission Control Protocol),大部分应用使用的正是 TCP 传输层协议,比如 HTTP 应用层协议。TCP 相比 UDP 多了很多特性,比如流量控制、超时重传、拥塞控制等,这些都是为了保证数据包能可靠地传输给对方。
UDP 相对来说就很简单,简单到只负责发送数据包,不保证数据包是否能抵达对方,但它实时性相对更好,传输效率也高。
应用需要传输的数据可能会非常大,如果直接传输就不好控制,因此当传输层的数据包大小超过 MSS(TCP 最大报文段长度) ,就要将数据包分块,这样即使中途有一个分块丢失或损坏了,只需要重新发送这一个分块,而不用重新发送整个数据包。在 TCP 协议中,我们把每个分块称为一个 TCP 段(TCP Segment)。

如何查看 TCP 的连接状态?
TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看。
TCP 分割数据
如果 HTTP 请求消息比较长,超过了 MSS 的长度,这时 TCP 就需要把 HTTP 的数据拆解成一块块的数据发送,而不是一次性发送所有数据。

三次握手过程?
一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态。
然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。
服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态。
客户端收到服务端发送的 SYN 和 ACK 之后,发送对 SYN 确认的 ACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了。
服务端收到 ACK 的 ACK 之后,处于 ESTABLISHED 状态,因为它也一发一收了。

P 协议会将传输层的报文作为数据部分,再加上 IP 包头组装成 IP 报文,如果 IP 报文大小超过 MTU(一个网络包的最大长度,以太网中一般为 1500 字节)就会再次进行分片,得到一个即将发送到网络的 IP 报文。
我们一般用 IP 地址给设备进行编号,对于 IPv4 协议, IP 地址共 32 位,分成了四段(比如,192.168.100.1),每段是 8 位。
为了方便查找,需要将 IP 地址分成两种意义:
IP功能:
此外 IP 中还包括 ICMP 协议和 ARP 协议。

在 IP 协议里面需要有源地址 IP 和 目标地址 IP:
如何查看当前系统的路由表。
在 Linux 操作系统,我们可以使用 route -n 命令查看当前系统的路由表。

以太网在判断网络包目的地时和 IP 的方式不同,因此必须采用相匹配的方式才能在以太网中将包发往目的地,而 MAC 头部就是干这个用的,所以,在以太网进行通讯要用到 MAC 地址。
MAC 头部是以太网使用的头部,它包含了接收方和发送方的 MAC 地址等信息,我们可以通过 ARP 协议获取对方的 MAC 地址。

在 MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输。
一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:
0800 : IP 协议0806 : ARP 协议既然知道要发给谁,按如何获取对方的 MAC 地址呢?
此时就需要 ARP 协议帮我们找到路由器的 MAC 地址。
在发包时:
查看 ARP 缓存内容
在 Linux 系统中,我们可以使用 arp -a 命令来查看 ARP 缓存的内容。

网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。
负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。
交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备。
计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址。
将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。
交换机的 MAC 地址表主要包含两个信息:
当 MAC 地址表找不到指定的 MAC 地址会怎么样?
交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包。
这样做不会产生什么问题,因为以太网的设计本来就是将包发送到整个网络的,然后只有相应的接收者才接收包,而其他设备则会忽略这个包。
此外,如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。
以下两个属于广播地址:
FF:FF:FF:FF:FF:FF255.255.255.255
路由器网络包经过交换机之后,现在到达了路由器,并在此被转发到下一个路由器或目标设备。
不过在具体的操作过程上,路由器和交换机是有区别的。
路由器基本原理
当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。