网络原理之TCP/IP2


前言

前面我们学习了TCP/IP五层模型,以及了解了网络传输的基本流程,下面我们针对应用层、传输层、网络层以及数据链路层,展开讲述其中最知名的协议。


一、应用层协议

在TCP/IP分层模型中,应用层是程序猿打交道最多的层,很多时候写代码,是涉及到应用层协议的。
在应用层,通常需要程序猿们自定义协议!!


1.1 为啥自定义协议

在当前软件(应用程序)种,要解决的业务场景是错综复杂的。不同的公司有不同的业务,不同的业务有着不同的流程,很难有一个通用的协议满足所有的业务需求的。

1.2 如何定义协议

1)结合需求,分析清楚,客户端(请求)和服务器(响应)之间要传递哪些数据。

例如,点外卖。
请求:你当前所处位置,你的身份信息
响应:商家信息、商品图片、价格…

  1. 明确传递的信息是以何种方式来组织的。

例如,最简单文本方式
请求:
约定请求是一行文本,字段之间用 ; 来分割。如:用户ID;地址\n。
响应也使用文本格式,响应有多行。每一行代表一个商家的信息。
如下:
商家名字,商家地址、商家简介\n
商家名字,商家地址、商家简介\n
商家名字,商家地址、商家简介\n
商家名字,商家地址、商家简介\n


进行上述约定的意义是:让客户端和服务器之间步调一致,约定好协议的具体内容之后,客户端按照这个协议格式构造请求并发送,服务器收到请求按照协议格式并解析。

1.3协议类型

约定的协议内容,和业务有很大相关性,约定协议组织格式和业务没有太大相关性。因此,大佬们发明了一些通用的数据组织格式。

1.3.1 XML格式

标签化数据组织方式,使用标签表示键值对,以及树形结构,所有的标签必须要成对出现。
在这里插入图片描述
在这里插入图片描述

1.3.2 json 格式

xml 格式在2010年之前很流行,后来人们觉得很麻烦,所以又引入了json格式。
在这里插入图片描述
在这里插入图片描述

上述xml和json都是按照文本方式来存储的。
优点:可读性好,用户不用借助其他工具,肉眼就能看懂含义。
缺点:效率不高,尤其占用较多带宽。xml中传入较多标签,json中传入很多key。


1.3.3 protobuffer

这是由谷歌发明,二进制表示数据方式。针对文本数据,使用二进制压缩了。
优点:占用带宽小
缺点:可读性不强


除此之外,应用层还有一些特定的协议,也是非常知名的,广泛使用的,如HTTP协议。

二、传输层协议

传输层虽然是操作系统内核实现好了,但是程序猿写代码,要调用系统提供的 Socket API完成网络编程,Socket 对象就属于传输层的内容。
传输层中最知名的协议就是UDP和TCP了。

2.1 端口号

首先在学习传输层协议之前先了解一下端口号的概念。
端口号的效果就是区分一个主机上具体的应用程序。

在同一个主机上,端口号不能被多个进程绑定。
UDP和TCP报头中都含有源端口、目的端口。
端口号表示范围:0->65535

注意!!
咱们的程序中设置的端口号,要从1024开始设置,0->1023端口称为“知名端口/具体端口号”这些端口号属于已经分配了一些知名广泛使用的应用程序了。

2.2 UDP协议

前面我们说到,UDP协议特点:无连接、不可靠传输、面向数据报、全双工。
学习一个协议,最重要的是了解它的协议报头。


下面是UDP协议的数据报:
在这里插入图片描述
UDP会把应用层得到的数据,通过UDP 中的 Socket 对象,在应用层数据报的基础上拼接几个字节的头。
在这里插入图片描述

2.2.1 UDP报文长度

UDP 数据报中有特定的属性,携带了一些重要的信息,对于 UDP 报头来说,一共8字节,分成了4个部分,每个部分2字节。
有上面可知,UDP的报文长度也是2字节,表示的范围0到65535,合计64kb左右,意思就是一个UDP数据报最大只能传输64kb的数据。


这里就会出现一个问题,如果应用层数据报大小超过了64kb怎么办?
解决方案有两种:
1.在应用层阶段,将应用层数据报进行手动分包,拆成多个包,再传给传输层。
2.使用TCP代替UDP,TCP没有这个限制。
更推荐的做法是第二种,因为第一种就要自己多编写代码,程序猿幸福感会变低。


2.2.2 UDP检验和

检验和的作用是验证传输的数据是否是正确的。

网络传输中,可能会收到一些干扰,出现 “比特翻转”现象,1变成0,0变成1.
还有网络传输实际传输的是光信号/电信号,这些信号可能收到电磁场、高能射线的物理影响。

这些现象是客观存在的,我们无法避免的,咱们能做的就是,及时识别出当前的数据是否出现问题,因此就引入了检验和来进行鉴别。


检验和是如何检验的呢?
我们通过对UDP数据报的报文内容,进行一系列数学运算,得到一个比较短的结果。如果数据内容一定,得到的检验和就一定,如果数据变了,检验和也就变了。
在这里插入图片描述
发送方会先对数据计算一个检验和,然后将数据和检验和一起发送给接收方,接收方根据接收到的数据再计算一遍校验和,如果两次检验和一致,说明传输的数据没问题;如果检验和不一致,传输的数据出错了。

这里,我们假设接收方接收到的数据出错了。
在这里插入图片描述
接收的错误数据计算出的检验和为0xccdd。此时数据传输时出错了!!


检验和生成算法有很多种,其中出名的几种。
1) CRC循环冗余检验
简单粗暴,把数据每一字节位循环累计往上加,如果累加溢出了,高位就不要了。

优点:好算
缺点:检验效果不理想。如果数据变动2个bit位,前一个字节+1,后一个字节-1,那么就会导致数据内容不一致,CRC还是一样。

2)MD5
MD5不是简单的循环累加,有一系列计算公式,来进行更复杂的数学运算。

特点:
1.定长的。无论你的原始数据多长,计算出来的MD5值都是固定的。
2.冲突概率小。原始数据即使改动一小点,计算出来的MD5都差别很大。
不可逆。通过原始数据计算MD5很容易,通过MD5还原原始数据很难。

正是基于MD5这些特性,让MD5有了更多使用场景。
1.检验和
2.计算哈希值
3.加密

2.3 TCP协议

TCP协议特点:有连接、可靠传输、面向字节流、全双工。
TCP协议报文结构如下:
在这里插入图片描述

2.3.2 TCP内部工作机制

TCP是一个复杂的协议,里面有很多机制,咱们主要提供TCP提供的10种比较核心的性质。

2.3.2.1 确认应答

确认应答是TCP实现可靠传输最核心机制。
下面以我和女神之间的故事展开之后的叙述。
在这里插入图片描述
A(我)给B(女神)发了个消息(请求),B收到之后立即给A返回一个应答报文(ACK),此时A收到ACK之后,就知道刚才发的数据是否顺利到了B。


考虑一个更复杂的情况:
本来我想达到正常的聊天顺序
在这里插入图片描述
但是由于网络上可能会存在 “后发先至”,这个情况,收到消息的顺序可能是下面这种结果。
在这里插入图片描述


网络中的数据也是同理,也存在后发先至的可能。
两个主机之间,线路有很多条,数据报走的路线也可能不同,数据报1经过的路由器/交换机和数据报2经过的交换机/路由器也可能不一样,有的转的很快,有的转的很慢…
网络后发先至的现象是客观存在的,我们无法避免,但是我们可以规避这种返回ACK报文顺序错乱导致的歧义。
那么,如何解决呢?
办法很简单,给请求的数据和应答报文都编上号。
在这里插入图片描述
当我们引入序号后,就不怕顺序乱了,即使顺序乱了,我们也能通过序号来判断当前应答报文是针对哪个请求的。


下面这一行,代表应答报文。
如果当前报文为应答报文,则ACK这一行为1,如果当前不是应答报文,ACK就为0。
在这里插入图片描述


实际上,TCP序号不是按照1、2、3这样标号的,TCP是面向字节流,序号也是按照字节方式来编的。
在这里插入图片描述
假设当前有两条请求,每一个数据都是1000字节,从1开始编号。
第一条请求,此时第一个字节序号编号就是1,第二个字节编号就是2… 但是由于这1000个字节都是属于第一个TCP请求报文,一个TCP报头中只记录当前第一个字节的编号。
接下来再发第二条请求,第一个字节编号就是1001,最后一个字节编号为2000,由于1001-2000都属于同一个TCP报文,所以TCP报头里只记录1001编号。

总结:TCP的字节序号是累加的,这个依次累加过程对于后一条数据来说,起始的字节序号就是上一个数据最后一个字节序号+1。每个数据报的序号只用第一个字节表示的序号即可。


确认序号的取值就是收到的请求数据最后一个字节序号+1。
在这里插入图片描述


小结:

TCP可靠传输主要通过确认应答机制来保证的。
通过应答报文,发送方就可以清楚知道传输是否成功。
进一步引入了序号、确认序号,针对多组数据进行详细分析。

2.3.2.2 超时重传

前面我们讨论确认应答,讨论的是传输顺利的情况,那么传输不顺利,丢包了呢?
丢包,涉及到两种情况:
1.发送的请求报文丢了
2.返回的ACK丢了
但是站在发送方的角度看,确实没收到ACK,具体也不知道哪种方式丢包了。此时TCP并没有不管,而是引入了重传机制,在丢包的时候,重新再发一次同样的数据。

所谓超时重传,就是超过了一定时间,还没收到响应,就重新传输。具体超过多长时间,是可以自己配置的,并且在不同系统上面默认值可能有差别。


问题又来了,由于超时重传,导致接收到重复消息,收到了很多次!!
在这里插入图片描述
对于主机B来说,1-1000就收到了两次,如果这个数据是支付请求呢?
TCP对于这种重复数据的传输,是有特殊处理的,去重。
如何理解去重?

TCP存在一个 “接收缓冲区”,每个TCP的socket都有一个缓冲区间,主机B接收到主机A的请求后,其实是主机B的网卡读取的数据,把这个数据放到B对应Socket的接收缓冲区,后续想使用,就从这个接收缓冲区中拿。
TCP根据发送请求的序号,很容易识别当前缓冲区这两条请求是否重复,如果重复,就直接丢弃一份,保证数据是不重复的。
另外,TCP还会对接收缓冲区内的数据进行重排序,保证和发送顺序一致。


小结:

TCP的可靠传输就是通过确认应答+超时重传保证的。
确认应答描述的是传输顺利的情况。
超时重传描述的是传输不顺利的情况。
这两者共同支撑了TCP的可靠性传输。

2.3.2.3 连接管理

TCP是有连接的。现在A和B需要通信,那么A就需要空间保存B的IP和端口号,B也要空间保存A的IP和端口号,此时A和B就建立连接了。把保存IP和端口的空间(数据结构)叫做 “连接(Connection)”。

那么啥叫 “断开连接”?
断开连接就是把连接的空间(数据结构)删除掉。

2.3.2.3.1 三次握手
2.3.2.3.1.1 理解三次握手

通过三次握手来建立连接。通信双方要各自记录对方的信息,彼此之间要互相认同。
还是以我和女神为例子。
此时女神是我的唯一,我也是女神的唯一,此时我与女神真正建立连接了。
此处就把每一次通信,就称为一次 “握手”。
在这里插入图片描述
在这里插入图片描述
从以上可以看出来,确实是经历了四次交互,但是其中两次是可以合并的。


小结:

所谓的三次握手,本质上是四次交互。通信双方各自要向对方发起建立连接的请求,双方各自返回ACK,但是中间两次交互可以合并成一次交互,因此就构成“三次握手”。

那么,为啥必须合并中间两次交互?
封装分用,封装分用两次一定比封装分用一次,成本更贵!!


三次握手除了解决通信双方彼此认同,还有一个重要作用:验证双方发送能力和接受能力是否正常。
三次握手也一定程度上保证了TCP可靠传输,但不是起关键作用,而是辅助。

在这里插入图片描述


三次握手的意义:
1.让双方各自建立对方的认同。
2.验证双方的发送能力和接收能力。
3.双方协调一些重要参数。

2.3.2.3.1.2 实际的三次握手

在这里插入图片描述
SYN:客户端主动给服务器发起建立连接请求,称为 “SYN”,同步报文段。
在这里插入图片描述

2.3.2.3.2 四次挥手
2.3.2.3.2 .1 理解四次挥手

TCP的断开连接使用四次挥手实现的。四次挥手和三次握手非常相似,都是通信双方各自向对方发送一个断开连接请求,再给各自返回一个响应。
还是以我和女神为例:
在这里插入图片描述
此时,我和女神的连接就彻底断开了。
注意!! 在断开连接中,中间的两次交互不能合并。

当两个请求发送的时机相同,可以合并。
当两个请求发送时机不同,不能合并。


那么,三次握手中的两次交互为啥能合并呢?
在这里插入图片描述
这是因为,三次握手中间两次交互是在同一时机下完成的,具体来说,三次握手是在操作系统内核里完成的,应用程序感知不到,也干预不了。服务器内核里收到SYN之后,会立即返回ACK,也会立即发送SYN。

四次挥手,中间两次交互为啥不能合并呢?
在这里插入图片描述
FIN的发起,不是由系统内核决定的,而是由应用程序,调用Socket的close方法或者进程的退出,才会触发FIN。ACK是系统内核决定的,收到FIN之后,会立即返回ACK。
在这里插入图片描述

2.3.2.3.2 .2 实际的四次挥手

在这里插入图片描述
四次挥手中有两个重要的TCP状态:
1.CLOSE_WAIT:出现在被动发起断开连接一方。
2.TIME_WAIT:出现在主动发起断开连接一方。

假设是客户端主动发起断开连接请求的,当客户端进入TIME_WAIT的时候,相当于四次挥手已经完成了,此时这里的TIME_WAIT要保持当前的TCP连接状态,不要立即释放。
那么,为啥不要立即释放呢?
因为此时最后一个ACK刚刚发出去,还没到呢,万一这个ACK丢包了呢,TIME_WAIT会等,如果过了一段时间,还没有收到重传FIN,就认为此时ACK没丢包,TIME_WAIT就可以释放了。
如果此时包确实丢了,重传FIN也丢了,那么客户端等了半天,没有收到重传FIN,就认为连接可以彻底释放了。

TIME_WAIT具体等待多长时间?
约定一个时间 2MSL,MSL指的是互联网上,两个节点之间数据传输消耗最大时间。通常情况下,1MSL=60s

2.3.2.3.2.3 小结

1.TCP作为一个有连接,就需要建立连接和断开连接。建立连接通过三次握手,断开连接通过四次挥手。
2.重点理解三次握手的意义。双方建立对方的认同。验证双方发送能力和接受能力。协调一些重要参数。
3.三次握手为啥不能是四次,为啥不能是两次。
4.四次挥手重点理解为啥是四次,理解FIN和ACK传输时机,以及TIME_WAIT的意义和作用。

2.3.2.4 滑动窗口

前面我们说的确认应答、超时重传、连接管理都是给TCP可靠传输提供保证。引入可靠性,其实是付出了代价,传输效率降低了。因此UDP没有可靠传输,传输效率快,所以TCP在尽可能想办法提高自己传输效率,但是再怎么提高,也不可能比UDP快。所以引入了滑动窗口

那么,滑动窗口是如何提高效率的呢?
本质上是降低了确认应答,等待ACK的时间。具体做法是,批量发送,批量等待。把多份等待时间合成一份了。

对于基本情况确认应答,主机A没发送一次请求,都需要等待ACK返回了之后,再发送第二个。
在这里插入图片描述

滑动窗口的做法就是不等待的批量发送一批请求,然后使用一份时间来等待一组数据的多个ACK。
把不需要等待,直接发送数据最大量,称为“窗口大小”。下面这个图,窗口大小为4000。
在这里插入图片描述
当批量发送了窗口大小的请求之后,发送方就要等待ACK了,啥时候继续往下发新的数据呢?等待啥时候结束?
这里,并不是说发送方等待所有的ACK都到达,才发下一条数据,而是等到一个ACK,就往下发一条。这样,就让等待的条数始终为4条。
在这里插入图片描述
上面等待的ACK是1001-5000,接下来收到了2001这个确认应答,说明1001-2000这个数据已经被确认应答了。此时就要发送5001-6000的数据,意味着等待ACK的范围就变成了2001-6000了。


上述情况,如果丢包了,怎么办?
1.ACK丢包了
不需要做任何处理,因为关键在于确认序号的含义,当前确认序号到达了,表示之前所有的数据都已经确认达到了。
在这里插入图片描述

2.请求数据丢包
由于1001-2000的数据丢包了,接下来2001-3000的数据到达主机B之后,B给A返回的确认序号仍然是1001,接下来的几个数据,B返回的都是1001,此时主机A感觉不对劲,说明1001-2000数据没有到达,A就需要对这个数据进行重传了。
在这里插入图片描述

上述丢包重传的方式,起了个名字叫做 “快速重传”,丢谁就重传谁。
如果当前传输数据密集,按照滑动窗口方式传输,此时还是根据快速重传处理丢包。如果传输数据稀松,就不按照窗口滑动方式传输,还是根据超时重传方式处理丢包。

2.3.2.5 流量控制

流量控制是干预活动窗口大小的机制。滑动窗口越大,传输的效率就越高,等待的ACK就越多,但是窗口也不能无限制的大。

如果窗口一直大,发送的请求数据越多,接收方可能处理不过来了,接收方的处理能力就是一个重要的约束,发送方的速度不能超过接收方的处理能力。
因此,流量控制要做的工作就是,根据接收方的处理能力,协调发送方的发送速率。

那么,如何衡量接收方的处理能力?
看接收方缓冲区内的剩余大小。
具体来说,就是A给B每次发送请求,B都会计算一下自己缓冲区内的大小,把这个值通过ACK返回给A,A会根据这个值决定下次要发送的速率(窗口大小)是多少。
在这里插入图片描述
这里的窗口大小为16位,那么是否表示最大的窗口为64kb呢?
并不是!! TCP为了让窗口更大,在选项部分引入了扩展因子,动态调节窗口大小。


发送方的窗口大小并不是固定的,也不是设置的,而是TCP根据传输过程动态变化的。
当窗口为0,发送方就暂停发送,暂停发送的期间,A会给B发一个探测报文,这个报文不携带任何业务信息,只是为了触发ACK查询窗口大小。
在这里插入图片描述

2.3.2.6 拥塞控制

流量控制和拥塞控制共同决定发送方发送窗口的大小。
流量控制考虑的是接收方的接收能力,拥塞控制描述的是中间节点的传输。


前面我们只考虑了A的发送速率,没有考虑中间节点。

在这里插入图片描述

接收方的处理能力,好量化,主要看接收缓冲区剩余大小。
中间节点不好量化,所以需要**“实验”**的方式来测出一个合适的值。

在这里插入图片描述
刚开始的时候,滑动窗口大小为1,以非常慢的速度发送数据。发现传输顺利,没丢包,第1轮窗口变为2,扩大一倍。初始阶段由于窗口较小,每一轮不丢包都是窗口指数增长。当增长到一定阈值之后,开始变为线性增长。接下来传输中一旦出现丢包了,说明发送速率已经接近网络的极限了,此时把窗口大小一下缩成很小,重复刚才指数增长和线性增长过程。

拥塞窗口并不是固定的值,而是一直动态变化的,随着时间推移,逐渐达到一种动态平衡。


小结:
流量控制和拥塞控制,共同决定滑动窗口大小,具体取两者较小的值。

2.3.2.7 延时应答

延时应答也会提升效率的方式。它的做法是,在接收方能够处理的情况下,尽量把窗口大点。
当主机B收到A的请求后,并不是立即给出ACK,而是稍微等会再返回。等待的时间内,接收方的应用程序会给缓冲区内的请求消费一些,此时剩余空间不就更大了吗。
在这里插入图片描述
实际上,延时应答采取的机制是,在滑动窗口下,ACK不是每条都返回,比如上图,就是隔一条返回一条。

实际上接收缓冲区剩余大小,取决于发送方发送速率,也取决于接收方处理能力。

2.3.2.8 捎带应答

捎带应答也是提高效率的一种方式。是在延时应答的基础上,引入的捎带应答。

服务器,客户端最典型的模型,就是 “一问一答”。
如下图,两个本身是不同时机,但是由于TCP的延时应答,可以将两条打包一起发送。
在这里插入图片描述

本来是不同时机,在延时应答机制下可能成为相同时机。
这与三次握手不同,三次握手中两次交互本身就是同一时机,是一定会合并的,此处的合并是一定概率合并。
在这里插入图片描述

2.3.2.9 面向字节流

面向字节流,引入了粘包问题。

前面我们知道,发送的请求其实是先存放在接收方对应的接收缓冲区里。
在这里插入图片描述
在这里插入图片描述
应用程序read读取的时候,读到哪里才算是一个完整的应用层数据报呢?
由于TCP是面向字节流的,可以一次读取一个字节,也可以一次读取多个字节。这就导致读的时候,读到的可能是半个应用层数据报,也可能是多个应用层数据报。


假如接收方缓冲区里有三个数据报。
在这里插入图片描述
应用层调用read。
如果read的是7个字节,正好读取到的就是aaaaaaa,一个完整的应用层数据报。
如果read的是8个字节,正好读取到的就是aaaaaaab,一个半应用层数据报。
如果read的是6个字节,正好读取到的就是aaaaaa,半应用层数据报。

那么如何解决?
应用层约定好应用层协议,尤其是明确包的明确分界。
1.使用分隔符
2.在每个包前加上长度

2.3.2.10 异常情况

传输过程中,出现了不可抗力。
1.进程崩溃了
2.主机正常关机

这两种过程,进程没了,对应的PCB也没了,对应的文件描述符表就没了,此时内核会继续完成四次挥手,其实此时是一个正常的断开连接过程。主机关机先杀死进程,再关机。

3.主机掉电
4.网线断开

这两种等不及四次挥手了。
如果是接收方掉电了,发送方仍然尝试发数据,发完数据等待ACK,等待不到超时重传,重传几次也等不到,会尝试TCP重置连接,显然这个操作也会失败,此时就放弃连接了。
如果是发送方掉电了,接收方没数据了,需要判断一下发送方挂了还是正在组织语言,接收方会周期性给发送方发送个消息,确认对方是否还在正常工作。可以通过心跳包来确认通信双方是否处于正常状态。

2.4 DNS协议

DNS叫做域名解析系统。比如我们经常说的 www.baidu.com 。其实网络上服务器要访问他,需要的是IP,但是IP地址不好记忆,于是使用一些简单的单词构成字符串表示这个地址。

每个域名丢对应一个/N个IP地址。


既然如此,那我们就需要把域名和IP地址对应上。
要求域名不能重复,那么全世界那么多网站,,如何保证域名唯一呢?
域名分级,分成一级域名、二级域名、三级域名…

www:一级域名
baidu:二级域名
com:三级域名

DNS服务器也随着域名分级,也分级了,查DNS服务器也是分级来查的,DNS服务器也分为一级DNS服务器、二级DNS服务器、三级DNS服务器…

三、网络层协议

3.1 IP协议

网络层最具代表性的协议就是IP。
如下图是一个IP协议数据报。
在这里插入图片描述

4位版本:取值为4(IPV4)、6(IPV6)。

4位首部长度:描述了IP报头有多长,可变长的。

8位服务类型:其实只有4位有效。4位只有其中一位为1,其余都为0。
这4位表示IP协议的四种形态/工作模式:最小延时、最大吞吐量、最高可靠性、最小成本。

16位总长度(字节数):描述了一个IP数据包的总长度(IP报头+IP载荷)。这个长度减去IP报头长度,就是TCP/UDP数据报长度。

这里的总长度是不是意味着一个IP数据包最大只能支持64kb?
确实是有这个限制的,但是IP自身就支持对包的拆分和组装。
例如,一个IP数据报携带的载荷太长了,超过了64kb,就会在网络层针对数据进行拆分把一个数据拆成多个数据报,再分别发送,接收方接收到重新组装。

在这里插入图片描述

16位标识:将一个IP数据报拆成多份,每一份的标识都是一样的。

3位标志:拆成多个包,以哪个包为结束标志。

13位片移量:拆成多个包的先后顺序。

8位生存时间(TTL):一个数据报在网络上能够传输的最大时间。

此处的时间不是“秒”,而是“次数”,一个数据构造出来会有一个初始的TTL(32、64、128…),这个数据报每经过一个节点转发,TTL都会-1,如果TTL一直减到0,数据报还没到达,此时就认为这个数据报永远也不能到达了,就丢弃。

8位协议:描述了当前载荷部分内容属于传输层哪个协议(TCP/UDP)。

16位首部检验和:此处指需要针对首部进行检验,因为IP载荷内容在传输层已经检验和过了。

32位源IP地址、32位目的IP地址:这是IP协议中,最重要的部分,但是日常生活中,为了便于理解,习惯使用点分十进制表示IP地址:127.0.0.1。


32位IP地址,换算一下大约有42亿9千万个表示IP地址的数字。很显然,不太够。
解决IP地址不太够的方式:
1.动态IP地址:此时可以省下一部分IP地址,但是这没有从根本上增加IP地址数量,而是提高了使用率。
2.NAT网络地址转换:本质上是使用一个IP代表一批设备,也能大大增加IP地址的利用率。

在NAT背景下,将IP分为两大类:
1.内网IP(私有IP):10.* 172.16.* -173.31.* 192.168.*
2.外网IP(公有IP):除了私网IP,剩下的都是公网IP了。

NAT要求,公网IP必须是唯一的,私网IP可以在不同的局域网里重复使用。
如果私网设备想要访问公网设备,就需要通过NAT设备,将私网IP进行映射,完成网络访问。
公网设备无法直接访问私网里的设备。
不同局域网的设备是不能直接相互访问的。

想象下面这样的场景。
当我的电脑想要访问对方服务器,中间经过的运营商路由器就会将我的IP地址通过NAT设备映射成路由器的外网IP。
此时只要有电脑想要通过运营商服务器给对方服务器交互,对方服务器端看到的源IP都一样。
在这里插入图片描述
如果多个电脑同时访问服务器,服务器的响应就会先交给运营商路由器,路由器根据这些电脑不同端口号来区分,决定发给哪个电脑。

因此,服务器能拿到的只是运营商路由器的IP,拿不到我的电脑内网IP。

NAT虽然能解决IP地址不够用情况,但是带来的副作用就是网络更加复杂了。

3.IPV6
IPV6从根本上解决了IP地址不够用的问题。IPV6使用16个字节表示。换算一下大约有:42亿42亿42亿*42亿个IP地址。

IPV6看起来虽然很美好,但是世界上仍然大多数还是使用NAT+IPV4+动态分配的方式组建网络的,原因很简单:贵死了!!!
并且IPV6和IPV4不兼容,更换IPV6就要需要更换路由器等设备,成本大大增加。

3.2 地址管理

把一个IP协议分成了两个部分:网络号+主机号

网络号:标识网段,保证相互连接的网段有不同的标识。
主机号:表示主机,同一个网段,网络号可以使用相同的,主机号必须不同。

如:IP地址192.168.1.10,192.168.1就是网络号,10就是主机号。


一个家里最常见的局域网示例。
在相同的网段内,网络号是可以相同的,主机号是不同的。
在不同的网段网络号是不能相同的。
在这里插入图片描述

那为啥要划分网络号和主机号,目的就是为了组网,关于组网相关的知识就不是我们程序猿该学的内容了。所以就不过多叙述了。

3.3 路由选择

路由选择简单了解一下即可。核心工作就是 “问路”!!
实际的网络传输是非常复杂的,数据在传输的时候,中间可能要经过很多节点。
每个路由器都会保存周围设备的信息(路由表)。每次有一个IP数据报经过都会匹配一下路由表,查看接下来怎么走,如果路由表上有匹配的项,就按照表上的走,如果没有匹配,会提供一个默认路径,继续走。继续沿着这个方向问。

没经过一次路由器,TTL就-1,如果TTL为0了,就代表当前数据永远到不了,就要被丢弃。

四、数据链路层协议

数据链路层考虑的是相邻两个节点如何进行传输,到底通过网线还是光纤传输。
这里最典型的传输协议就是以太网。

4.1以太网

如下是以太网帧格式:
一个以太网数据帧=帧头+载荷+帧尾
在这里插入图片描述

帧头:源地址、目的地址、协议类型。

此处地址不是IP地址了,而是mac地址,每个设备也都对应一个mac地址,不是动态分配的,而是由网卡出厂的时候设置好的。

总结

关于网络原理,我们重点要学习应用层和传输层,这是和咱们写代码相关的,网络层和数据链路层,简单了解。如果小伙伴们有觉得小编写的不错的,或者对你与帮助的,希望能点点关注,谢谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值