TCP/IP 协定栈是一系列网络协议的总和,是形成网络通信的外围骨架,它定义了电子设备如何连入因特网,以及数据如何在它们之间进行传输。TCP/IP 协定采纳 4 层构造,别离是应用层、传输层、网络层和链路层,每一层都呼叫它的下一层所提供的协定来实现本人的需要。因为咱们大部分工夫都工作在应用层,上层的事件不必咱们操心;其次网络协议体系自身就很简单宏大,入门门槛高,因而很难搞分明 TCP/IP 的工作原理,艰深一点讲就是,一个主机的数据要通过哪些过程能力发送到对方的主机上。接下来,咱们就来摸索一下这个过程。
0、物理介质
物理介质就是把电脑连接起来的物理伎俩,常见的有光纤、双绞线,以及无线电波,它决定了电信号 (0 和 1) 的传输方式,物理介质的不同决定了电信号的传输带宽、速率、传输间隔以及抗干扰性等等。
TCP/IP 协定栈分为四层,每一层都由特定的协定与对方进行通信,而协定之间的通信最终都要转化为 0 和 1 的电信号,通过物理介质进行传输能力达到对方的电脑,因而物理介质是网络通信的基石。
上面咱们通过一张图先来大略理解一下 TCP/IP 协定的根本框架:
当通过 http 发动一个申请时,应用层、传输层、网络层和链路层的相干协定顺次对该申请进行包装并携带对应的首部,最终在链路层生成以太网数据包,以太网数据包通过物理介质传输给对方主机,对方接管到数据包当前,而后再一层一层采纳对应的协定进行拆包,最初把应用层数据交给利用程序处理。
网络通信就好比送快递,商品里面的一层层包裹就是各种协定,协定蕴含了商品信息、收货地址、收件人、联系方式等,而后还须要配送车、配送站、快递员,商品能力最终达到用户手中。
个别状况下,快递是不能中转的,须要先转发到对应的配送站,而后由配送站再进行派件。
配送车就是物理介质,配送站就是网关,快递员就是路由器,收货地址就是 IP 地址,联系方式就是 MAC 地址。
快递员负责把包裹转发到各个配送站,配送站依据播种地址里的省市区,确认是否须要持续转发到其余配送站,当包裹达到了指标配送站当前,配送站再依据联系方式找到收件人进行派件。
有了整体概念当前,上面咱们具体理解一下各层的分工。
1、链路层
网络通信就是把有特定意义的数据通过物理介质传送给对方,单纯的发送 0 和 1 是没有意义的,要传输有意义的数据,就须要以字节为单位对 0 和 1 进行分组,并且要标识好每一组电信号的信息特色,而后依照分组的程序顺次发送。以太网规定一组电信号就是一个数据包,一个数据包被称为一帧,制订这个规定的协定就是以太网协定。一个残缺的以太网数据包如下图所示:
整个数据帧由首部、数据和尾部三局部组成,首部固定为 14 个字节,蕴含了指标 MAC 地址、源 MAC 地址和类型;数据最短为 46 个字节,最长为 1500 个字节,如果须要传输的数据很长,就必须宰割成多个帧进行发送;尾部固定为 4 个字节,示意数据帧校验序列,用于确定数据包在传输过程中是否损坏。因而,以太网协定通过对电信号进行分组并造成数据帧,而后通过物理介质把数据帧发送给接管方。那么以太网如何来识接管方的身份呢?
以太网规协定定,接入网络的设施都必须装置网络适配器,即网卡,数据包必须是从一块网卡传送到另一块网卡。而网卡地址就是数据包的发送地址和接管地址,也就是帧首部所蕴含的 MAC 地址,MAC 地址是每块网卡的身份标识,就如同咱们身份证上的身份证号码,具备寰球唯一性。MAC 地址采纳十六进制标识,共 6 个字节,前三个字节是厂商编号,后三个字节是网卡流水号,例如 4C-0F-6E-12-D2-19
有了 MAC 地址当前,以太网采纳播送模式,把数据包发给该子网内所有主机,子网内每台主机在接管到这个包当前,都会读取首部里的指标 MAC 地址,而后和本人的 MAC 地址进行比照,如果雷同就做下一步解决,如果不同,就抛弃这个包。
所以链路层的次要工作就是对电信号进行分组并造成具备特定意义的数据帧,而后以播送的模式通过物理介质发送给接管方。
这里分享几个视频解说、手写代码实现一个协定栈:
Linux 服务器开发——tcp 训练营 epoll 与网络 io 单线程,多线程 丨手写代码丨后盾开发丨 Linux 网络编程丨底层原理 上_哔哩哔哩 (゜ - ゜)つロ 干杯~-bilibili
Linux 服务器开发——tcp 训练营 epoll 与网络 io 单线程,多线程 丨手写代码丨后盾开发丨 Linux 网络编程丨底层原理 下_哔哩哔哩 (゜ - ゜)つロ 干杯~-bilibili
Linux 服务器开发——tcp 训练营,滑动窗口,udp 并发,状态迁徙图,挥手中间状态丨网络底层原理丨手写代码实现网络协议栈 上_哔哩哔哩 (゜ - ゜)つロ 干杯~-bilibili
Linux 服务器开发——tcp 训练营,滑动窗口,udp 并发,状态迁徙图,挥手中间状态丨网络底层原理丨手写代码实现网络协议栈 下_哔哩哔哩 (゜ - ゜)つロ 干杯~-bilibili
更多 Linux C/C++ 后盾服务器开发知识点分享 +qun720209036:内容包含 C /C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,P2P,Skynet,Linux 内核,Docker,TCP/IP,协程,DPDK 多个高级知识点。
2、网络层
对于下面的过程,有几个细节问题值得咱们思考:
发送者如何晓得接收者的 MAC 地址?
发送者如何晓得接收者和本人同属一个子网?
如果接收者和本人不在同一个子网,数据包如何发给对方?
为了解决这些问题,网络层引入了三个协定,别离是 IP 协定、ARP 协定、路由协定。
【1】IP 协定
通过后面的介绍咱们晓得,MAC 地址只与厂商无关,与所处的网络无关,所以无奈通过 MAC 地址来判断两台主机是否属于同一个子网。
因而,网络层引入了 IP 协定,制订了一套新地址,使得咱们可能辨别两台主机是否同属一个网络,这套地址就是网络地址,也就是所谓的 IP 地址。
IP 地址目前有两个版本,别离是 IPv4 和 IPv6,IPv4 是一个 32 位的地址,常采纳 4 个十进制数字示意。IP 协定将这个 32 位的地址分为两局部,后面局部代表网络地址,前面局部示意该主机在局域网中的地址。因为各类地址的分法不尽相同,以 C 类地址 192.168.24.1 为例,其中前 24 位就是网络地址,后 8 位就是主机地址。因而,如果两个 IP 地址在同一个子网内,则网络地址肯定雷同。为了判断 IP 地址中的网络地址,IP 协定还引入了子网掩码,IP 地址和子网掩码通过按位与运算后就能够失去网络地址。
因为发送者和接收者的 IP 地址是已知的(应用层的协定会传入),因而咱们只有通过子网掩码对两个 IP 地址进行 AND 运算后就可能判断单方是否在同一个子网了。
【2】ARP 协定
即地址解析协定,是依据 IP 地址获取 MAC 地址的一个网络层协定。其工作原理如下:
ARP 首先会发动一个申请数据包,数据包的首部蕴含了指标主机的 IP 地址,而后这个数据包会在链路层进行再次包装,生成以太网数据包,最终由以太网播送给子网内的所有主机,每一台主机都会接管到这个数据包,并取出标头里的 IP 地址,而后和本人的 IP 地址进行比拟,如果雷同就返回本人的 MAC 地址,如果不同就抛弃该数据包。ARP 接管返回音讯,以此确定指标机的 MAC 地址;与此同时,ARP 还会将返回的 MAC 地址与对应的 IP 地址存入本机 ARP 缓存中并保留肯定工夫,下次申请时间接查问 ARP 缓存以节约资源。cmd 输出 arp -a 就能够查问本机缓存的 ARP 数据。
【3】路由协定
通过 ARP 协定的工作原理能够发现,ARP 的 MAC 寻址还是局限在同一个子网中,因而网络层引入了路由协定,首先通过 IP 协定来判断两台主机是否在同一个子网中,如果在同一个子网,就通过 ARP 协定查问对应的 MAC 地址,而后以播送的模式向该子网内的主机发送数据包;如果不在同一个子网,以太网会将该数据包转发给本子网的网关进行路由。网关是互联网上子网与子网之间的桥梁,所以网关会进行屡次转发,最终将该数据包转发到指标 IP 所在的子网中,而后再通过 ARP 获取指标机 MAC,最终也是通过播送模式将数据包发送给接管方。
而实现这个路由协定的物理设施就是路由器,在盘根错节的网络世界里,路由器扮演者交通枢纽的角色,它会依据信道状况,抉择并设定路由,以最佳门路来转发数据包。
【4】IP 数据包
在网络层被包装的数据包就叫 IP 数据包,IPv4 数据包的构造如下图所示:
IP 数据包由首部和数据两局部组成,首部长度为 20 个字节,次要蕴含了指标 IP 地址和源 IP 地址,指标 IP 地址是网关路由的线索和根据;数据局部的最大长度为 65515 字节,实践上一个 IP 数据包的总长度能够达到 65535 个字节,而以太网数据包的最大长度是 1500 个字符,如果超过这个大小,就须要对 IP 数据包进行宰割,分成多帧发送。
所以,网络层的次要工作是定义网络地址,辨别网段,子网内 MAC 寻址,对于不同子网的数据包进行路由。
3、传输层
链路层定义了主机的身份,即 MAC 地址,而网络层定义了 IP 地址,明确了主机所在的网段,有了这两个地址,数据包就从能够从一个主机发送到另一台主机。但实际上数据包是从一个主机的某个应用程序收回,而后由对方主机的应用程序接管。而每台电脑都有可能同时运行着很多个应用程序,所以当数据包被发送到主机上当前,是无奈确定哪个应用程序要接管这个包。
因而传输层引入了 UDP 协定来解决这个问题,为了给每个应用程序标识身份,UDP 协定定义了端口,同一个主机上的每个应用程序都须要指定惟一的端口号,并且规定网络中传输的数据包必须加上端口信息。这样,当数据包达到主机当前,就能够依据端口号找到对应的应用程序了。UDP 定义的数据包就叫做 UDP 数据包,构造如下所示:
UDP 数据包由首部和数据两局部组成,首部长度为 8 个字节,次要包含源端口和指标端口;数据最大为 65527 个字节,整个数据包的长度最大可达到 65535 个字节。
UDP 协定比较简单,实现容易,但它没有确认机制,数据包一旦收回,无奈晓得对方是否收到,因而可靠性较差,为了解决这个问题,进步网络可靠性,TCP 协定就诞生了,TCP 即传输控制协议,是一种面向连贯的、牢靠的、基于字节流的通信协议。简略来说 TCP 就是有确认机制的 UDP 协定,每收回一个数据包都要求确认,如果有一个数据包失落,就收不到确认,发送方就必须重发这个数据包。
为了保障传输的可靠性,TCP 协定在 UDP 根底之上建设了三次对话的确认机制,也就是说,在正式收发数据前,必须和对方建设牢靠的连贯。因为建设过程较为简单,咱们在这里做一个形象的形容:
主机 A:我想发数据给你,能够么?
主机 B:能够,你什么时候发?
主机 A:我马上发,你接着!
通过三次对话之后,主机 A 才会向主机 B 发送正式数据,而 UDP 是面向非连贯的协定,它不与对方建设连贯,而是间接就把数据包发过来了。所以 TCP 可能保障数据包在传输过程中不被失落,但美妙的事物必然是要付出代价的,相比 UDP,TCP 实现过程简单,耗费连贯资源多,传输速度慢。
TCP 数据包和 UDP 一样,都是由首部和数据两局部组成,惟一不同的是,TCP 数据包没有长度限度,实践上能够有限长,然而为了保障网络的效率,通常 TCP 数据包的长度不会超过 IP 数据包的长度,以确保单个 TCP 数据包不用再宰割。
总结一下,传输层的次要工作是定义端口,标识应用程序身份,实现端口到端口的通信,TCP 协定能够保障数据传输的可靠性。
4、应用层
实践上讲,有了以上三层协定的反对,数据曾经能够从一个主机上的应用程序传输到另一台主机的应用程序了,但此时传过来的数据是字节流,不能很好的被程序辨认,操作性差。因而,应用层定义了各种各样的协定来标准数据格式,常见的有 HTTP、FTP、SMTP 等,HTTP 是一种比拟罕用的应用层协定,次要用于 B / S 架构之间的数据通信,其报文格式如下:
在 Resquest Headers 中,Accept 示意客户端冀望接管的数据格式,而 ContentType 则示意客户端发送的数据格式;在 Response Headers 中,ContentType 示意服务端响应的数据格式,这里定义的格局,个别是和 Resquest Headers 中 Accept 定义的格局是统一的。
有了这个标准当前,服务端收到申请当前,就能正确的解析客户端发来的数据,当申请解决完当前,再依照客户端要求的格局返回,客户端收到后果后,依照服务端返回的格局进行解析。
所以应用层的次要工作就是定义数据格式并依照对应的格局解读数据。
5、全流程
首先咱们梳理一下每层模型的职责:
链路层:对 0 和 1 进行分组,定义数据帧,确认主机的物理地址,传输数据;
网络层:定义 IP 地址,确认主机所在的网络地位,并通过 IP 进行 MAC 寻址,对外网数据包进行路由转发;
传输层:定义端口,确认主机上应用程序的身份,并将数据包交给对应的应用程序;
应用层:定义数据格式,并依照对应的格局解读数据。
而后再把每层模型的职责串联起来,用一句通俗易懂的话讲就是:
当你输出一个网址并按下回车键的时候,首先,应用层协定对该申请包做了格局定义;紧接着传输层协定加上了单方的端口号,确认了单方通信的应用程序;而后网络协议加上了单方的 IP 地址,确认了单方的网络地位;最初链路层协定加上了单方的 MAC 地址,确认了单方的物理地位,同时将数据进行分组,造成数据帧,采纳播送形式,通过传输介质发送给对方主机。而对于不同网段,该数据包首先会转发给网关路由器,通过屡次转发后,最终被发送到指标主机。指标机接管到数据包后,采纳对应的协定,对帧数据进行组装,而后再通过一层一层的协定进行解析,最终被应用层的协定解析并交给服务器解决。
6、总结
以上内容是对 TCP/IP 四层模型做了简略的介绍,而实际上每一层模型都有很多协定,每个协定要做的事件也很多,但咱们首先得有一个清晰的脉络构造,把握每一层模型最根本的作用,而后再去丰盛细枝末节的货色,兴许会更容易了解。