网络基础(三)

我们网络协议栈呢,从上往下,分别是,应用层、传输层、网络层、数据链路层。我们现在已经搞定了应用层、传输层,下面我们要解决的就是网络层了,但是在此之前,我们还要回答一下,传输层解决的是什么呢?它主要解决的是可靠性的问题,也就是说,它是用来保证,当我们的主机相隔千里之外的可靠性问题。应用层解决的又是什么呢?它主要解决的是,诸如序列化和反序列化的问题,读取完整报文的问题,以及协议处理的问题,应用层在往上就是将我们的数据提取出来了,然后就是处理数据。我们的协议呢,重点是将读取数据等做完就可以了,比如网络版本计算器,它将我们的数据提取出来,然后在应用层再往上就是使用多进程和多线程,以及我们后面还要讲的技术来进行对数据做业务处理。所谓的业务呢,就是将拿到的数据进行做各种的判断,计算,然后将数据存储或者返回给客户等工作。
》我们现在清楚的时候,应用层和传输层可以可靠的把数据发送给对方,然后对方上层就可以做处理了,但是,这里面对的新问题就是,你不要忘了,TCP面对的数据呢,是和我们相隔千里之外的,中间呢还有各种各样的数据,诸如路由器、交换机等设备,你现在要把数据千里之外送到对方传输层,然后向上交给应用层,这是我们在逻辑上这样理解。
》但是,你要在千里之外,将数据传输到对方的传输层,你是不是要先决定,将我们的数据跳转到下一个报文处,你得一跳一跳,经过路径选择把数据才能到达目标主机,才能向上交付。所以,要把数据从千里之外,从一端到另一端,你得先解决主机到主机,点对点这样的问题。
》接下来呢,我们要谈一个问题,要用到网络层,它的典型协议就是IP协议。我们首先要来给IP下一个定义。
》其实我们前面说解决点对点问题,是不太准确的,我们应该这么说,根据我们的理解知道,在中间路由器过程中呢,数据最多只会交付到网络层,传输层和对方的传输层呢,只有到达目标主机才将数据交付给传输层,中间通过的主机呢,数据只会到网络层,所以,我们应该这么去说,一跳一跳应该严格意义上来讲是属于链路层阶段。
》我们现在要做的是,你要保证我们的数据可靠的从主机A送到主机B,前提条件是你得先能送到对端主机,这句话有点怪,再说一遍。就是你要可靠的将数据送到对端主机,前提条件是你得能把数据送到对方主机的网络层。这句话什么意思呢?就要给网络层IP协议下一个定义:让我们主机具有一种能力,将数据从主机A送到主机B的能力。
》给大家说一下,我们刚刚说的有一点问题,传输层,它解决的是可靠的问题,什么是可靠呢?就是100%的问题,它解决的是可靠性问题,它并不传送数据,很奇怪,你前面讲过传输层将数据发送到网络里面,不是传输层将数据发送到网络里面,而是传输层将数据向下交付到网络层,那么传输层更多给我们提供的是,诸如丢包重传、滑动窗口、流量控制等等策略,传输层给我们提供的是各种策略,而我们将数据从A主机远距离发送到B主机,要具有这种能力的话,是由我们的IP解决的。当我们能够把数据从主机A送到主机B了,然后才是你怎么一跳一跳的,这是链路层决定的,我们后面会说。
》下面,我们要做的工作是,你如何去理解这种能力呢?我们讲一个小故事来理解这种能力。学校里有一名同学,数学成绩特别好,私下议论的时候,都说张三的数学特别好,我感觉他每次都有考100分的能力,周围的同学也点头同意。好的,那么其中,张三具有考100分的能力的时候,你是如何理解这句话呢?是不是我们具有考100分的能力,就能**每一次都做到呢?**我说张三每次考试都具有考100分的能力,是不是就是意味着现实生活他一定能做到呢?不一定。什么叫做具有考100分的能力呢?正常的认识是,**他有非常大的概率考到100分!**现在的问题是,张三有这个能力了,我现在要求的不是他有较大概率考到100分,我想让他100%考到100分。那怎么让他考到100分呢?上天就是不公平,张三就是有一个特别聪明的大脑,同时张三还有一个非常厉害的老爹,他老爹是教学主任,只要张三考试考到100分还好,如果考不到100,那么教导主任就会说,这次考试不算,我们重新再考,如果张三下次考试还是99,怎么办呢?那就还是不算,再重新考,知道张三考到100分。甚至呢,我们还可以定策略,让张三单独去考,直到张三考到100分。
》我们张三同学呢,就相当于网络层的IP,然后他爹教务主管就相当于传输层,当张三没有考到100分时,那就给他提供相关的策略,让它去考。这不就是丢包重传嘛,所以呢,网络层,解决的是从主机A跨网络将数据送到主机B的能力。所以,**网络层提供的是:将数据从A主机,跨网络,送到B主机。**我可没有说它是可靠哦。我们说的是,IP呢解决的是,将数据从A主机跨网络送到B主机,这是它的能力,并不代表可靠的到达对方。一旦,底层发送数据,送到对方那就还好,没送到,就会告知传输层没有发送成功,然后传输层识别到是不是超时了,是不是丢包了等,然后才做我们想关的重传,所以,IP、TCP可以这样去理解,当我们有了IP呢,我们是可以将数据送到对方,当中间有可能会丢包怎么办呢?不要紧,再结合TCP就可以做到,TCP/IP:将我们的数据可靠的从A主机,跨网络,送到B主机
》所以,当我们体会到这一点时,你再想想,什么叫做TCP/IP协议栈呢?TCP/IP协议栈属于操作系统内部实现网络通信的策略,它呢,就是为了将数据可靠的从主机到主机。这不就是我们解决了长距离通信的原因/目的嘛。
》所以,TCP/UDP提供的是策略,就是当底层没有办好,我该怎么办的问题。无论是面向连接,还是超时重传,还是丢包重传、按序到达,还是拥塞控制、流量控制等,这些都是策略,只有真正底下网络层帮我们进行办事的。我们在网络当中传送的报文呢,我们叫做IP报文。我们把传输层的叫做数据段,然后在网络层呢,我们叫做IP报文。

在这里插入图片描述
我们将预备工作做好了,我们回过头看图片,这就是一个较为复杂的网络结构。下面呢,我们想把主机B的数据送到主机C,那么IP呢解决的就是将数据从主机B送至主机C,这就是它的能力,我可没说可靠。现在呢,我们应该把问题在聚焦一下,就是,IP是如何将数据经过跨网络送到主机C呢?这就涉及到重要的概念,路径选择。
》当然,路径选择呢,要查路由表,形成路由表不是我们的重点,我们的重点是学习IP本身。所以接下来我们要学习一些概念。

主机:配有IP地址,但是不进行路由控制的设备;这句话本来说的就有一点问题,就是单个主机只要有网络层,它就具有路由的能力,所以主机呢是具有路由控制的能力。
》路由器:它配有IP,主要是在路上进行数据报转发的设备。
》节点:主机和路由器的统称。
》往后我们在表述的时候,主机、路由器这样的概念,我们也不做明显区分。一般我们说主机的时候呢,就是有两个完整的计算机,也可能就是中间的路由器,但是我们说路由器的话,那就肯定是路由器了。
》下面呢,我们要谈论的就是,TCP要解决策略问题,保证可靠性,而IP呢,解决的是长距离传送的问题,为我们提供了一种将数据从主机A跨网络送到主机B的能力。下面呢的问题就是,我们的IP格式是什么样子的呢?所以,我们先来看看IP的格式。
在这里插入图片描述
我们这里有一张图,我们整体看到我们的报文的格式呢,也是按照我们之前理解,和我们的TCP是非常的相似的。整体的相似体现在哪里呢?体现在IP的报头整体长度也是20个字节,它也有选项字段,我们不管,所以,我们就有了标准长度的IP报头20字节。宽度呢,就是0~31,4个字节,一共有5行,这5行总体的报文大小呢,和我们的TCP也是一样的,所以我们的IP协议和TCP协议的格式,标准长度呢可能就有点像,都是20字节。当然,大家也能够根据前面学习的协议,也能推出IP协议在底层也是用的位段来表示的。

》下面我们来谈第一个,就是“4位版本”字段。4位版本呢,一般填的都是IPV4,而我们说的IPV6呢,是用128bit位表示的IP地址,但是IPV6和我们的IPV4是不兼容的,不兼容呢,所以4位版本都是IPV4,如果是IPV6就是另一套策略了。

》另一个字段“4位首部长度”。说白了就是我们整个报头的长度。不知道大家还记不记得我们学TCP的时候,TCP协议格式里面也有4位首部长度字段,所以我们可以推断出,这里4位首部长度应该是0000~1111,即取值范围是[0,15],但是我们的IP报文的标准长度就是20字节,你怎么表示呢?所以,它的单位长度呢,也是4字节! 这个定义呢,和我们TCP报头的定义也是一摸一样的。所以,如果我们的IP报文是标准长度,那么我4位首部长度这里填的应该是0101。

》再下来,“8位服务类型”字段。一般我们很少去使用,我们一般用IP呢,这个地方就不是我们去考虑的了。 这个字段呢,有3个bit位是被弃用的,4位TOS字段, 和1位保留字段(必须置为0). 4位
TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于
ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要.这个东西我们不怎么去用它,这个字段呢世界和大部分场景去用,但是我们一般是不会去管它。这个我们就不考虑了。

》再下来就是,“16位总长度”。我们发现IP是有总长度的,所以,我们学习IP第一件事情也和之前一样,要回答两个问题,如何封装和解包?如何分用,向上交付?说白了,大家也知道,我们对应的IP协议呢,它脑袋顶上还有我们对应的UDP,还是TCP,当然还会有其他协议。换而言之呢,我们网络收到了特定的IP报文,我们究竟将我们收到的IP报文向上交付给TCP还是UDP呢?正如我们传输层又要向上交付给哪个端口的进程一样。
》我们第一个问题其实已经能够回答了,因为我们有4位首部长度字段,我们将来在读取时,可以先读取1字节,然后将4位首部长度字段提取出来,然后我们再将 剩下的3字节读取出来,那么16位总长度字段我们是能够读出来。或者我干脆将20字节全读上去,分析的时候呢,就是将4位首部长度提取出来,16位总长度提取出来。然后噢根据首部长度算出报头,然后就可以将报头拿到了,接着用用,16位总长度-报头长度=有效载荷,其中剩下的就是有效载荷了。其中,我们能够再IP这里完成封装和解包,是可以做到的。
》再下来就是,在IP当中呢,如何分用,向上交付呢(UDP、TCP)?那么,在报头字段当中,有一个字段就是“八位协议”字段。它代表的就是,比如说,我是发送方,要通过IP向你发消息,我是TCP,所以,我们在发送报文时,IP知道,自己的数据是从TCP协议来的,所以,当它在构建IP报文的时候,就将“8位协议”字段填成UDP或者TCP,填成对应的协议呢,当我们对应的接收端收到了IP报文时,就可以读取前20字节,然后进行解包,将有效载荷读取出来,然后根据“8位协议”字段,知道我们的有效载荷是要交付给TCP,所以,它又把数据交给了上一层传输层中的TCP协议的接收缓冲区里面,然后,至此接收方就能拿到数据了。所以呢,我们如何向上分用,是由它的“8位协议”字段来决定。
》所以IP报文中的,4位版本、4位首部长度、8位服务类型、16位总长度、8位协议、16位首部校验字段(很容易理解),我们就都解释完了。下面呢,我们重点来谈的呢,就是剩下的这些字段。剩下的这些字段,毫无疑问 ,要给大家聊呢,当然跟之前的讲法一样,也要结合我们IP的一些特征去谈,其中我们想要重点去聊的呢,是16位标识、3位标志、13位片偏移这几个字段。当然等我们聊到这几个字段,也会给大家说,它其实也不是重点,这个关于IP分片的问题,它也不是重点,但是呢,它很重要,它主要体现在我们未来理解IP的完整过程是很重要的。在面试当中,它确实不怎么会被问到,但是我还是想给大家说一下。但在谈它们的时候,我们先将好理解的字段说一下。

》“8位生存时间TTL”字段。 当我们在路上进行路由的时候呢,我们的IP呢,有一个特点,它在路由的时候,肯定会到一个一个的路由器当中,然后最后交付到我们的目标主机。现在的问题是什么呢?如果今天,我们发出去的IP报文,它本身在进行我们路由器转发的时候,如果我们的网络有bug,或者目标主机不可达,比如说目标主机很远,或者目标主机,已经在算法当中找不到它了,或者是我们网络很复杂,有bug,那么其中,在路由的时候,有可能会出现,IP报文在网络当中长时间游离。所以,由于网络的bug或者,对端主机不可达等不可控因素等存在,导致我们的IP报文在我们的网络中长时间游离而不消失。
》举一个例子,就比如路由器出故障了,IP报文来回在互相之间转发。那么如果没有对IP报文做生命周期的约束的话,那么就会导致,网络当中的游离报文会越来越多,游离报文呢,其实已经没有多大意义了,你再怎么转发,也出不去,还要占用路由器相关的资源。所以呢,我们这个报文长时间的在网络当中转发而不消失,时间一久只会导致我们的网络周期性的出现网络问题。所以,我们就必须得给我们的IP报文设置生命周期。
》什么意思呢,就是我们在发送报文的时候,为该报文设置我们的报文生命周期,比如5,代表什么意思呢?就是没经过一个路由器转发,那么该报文TTL生存时间进行–,每经过一个路由器就将我们的TTL进行–,当下一个路由器对他做–的时候,如果TTL=0或者是<0了,我们没有必要再转发这个报文了,此时直接将该报文进行丢弃,也就是换句话说,我们的这个报文生存时间被转发到目标主机的时候呢,一定要保证生存时间没有问题,如果有问题,就有可能在路上就将该报文作为废弃报文直接丢弃掉。经过这样的策略呢,无论是因为我们的网络有bug,形成了环路网络,还是因为长距离,目标主机不可达等原因,最终呢,我们都可以在一段时间后,这个报文自动被丢弃了,这就是报文的生存时间。
》有人会说,这个生存时间一般是多少呢?短了不行,长了也不行。这个你不用担心,因为IP报文在转发的时候,它的生存时间在设置的时候,不会设置的很小,它设置好之后呢,绝对能保证在全世界范围内呢,两个主机能够联通。弄一个TTL主要是为了防止网络出现问题。这个报文生存时间呢,是有自己的算法的,因为我们后面会有子网划分的,路由器是可以根据IP地址,去判定当前主机,就是,判定目标主机和我们的当前主机的距离问题。就有点像我们的学校的学号,我们可以根据学号来判别出来,该学生是哪个年纪,哪个学院,哪个专业,哪个班级,班级的第几号来确定该学生。子网划分呢,我们也不用太关心,关心这个的都是路由器的设计者。

》再来呢,就是比较重要的“32位源/目的IP地址”字段。我们的IP报文呢,是会携带源IP和目的IP。这就是我们发现一个问题,我们自己曾经写网络套接字的时候,我们绑定的时候,是要绑定bind()套接字的,什么是套接字呢?就是IP地址 + 端口号Port。
》曾经我们说过,IP代表在公网当中的唯一一台主机,端口号port标定的是该主机上的唯一的进程,所以,我们可以用IP地址+端口号port来标定唯一主机上的唯一进程。所以,我们惊奇的发现,端口号是给那一层用的呢?根据报头,它是给UDP/TCP用的,因为传输层的上方就是应用层,所以,端口号port就是给UDP/TCP他们两个用的。而我们的IP地址用来定位主机,它就给了我们IP报文,因为IP报文呢,是负责将数据送到远端的主机的,所以,就必须要有源IP和目的IP。所以,我们曾经在写套接字,绑定bind()的时候,绑定你的IP地址,connet()远端服务器时,这里3位目的IP地址填的就是你连接的目标是谁 ,32位源IP地址填的就是当前你是谁。所以,把IP地址就填充到了我们对应的报文当中。

下面,我们是时候要研究下一个话题,我可以看到,第1、3、4、5行,是很容易理解的,其中最难理解的是,第2行,这里有3组字段,我们来认识一下。
》学习IP呢,我们重点要再来关注一个比较重要的点呢,我们称之为,分片问题。那么我们就要切换到OSI的下一层,数据链路层!
》数据链路层又一个规定,这个规定呢就是,我们想使用下一层的数据链路层呢,谁使用数据链路层呢?是我们的网络IP报文,要向链路层交付。链路层呢,它有一个规定,它所能够单次转发的有效载荷呢是有上限的。这个呢,主要是由于一些电器特征,不知道大家还记不记,如果我们在局域网当中通信,我们其实是基于碰撞域的。也就是说,我在局域网当中,我想给你说句话,其他人不能说话,其他人一说话呢,就可能和我冲突了,所以,我一说话,张三你站起来,你作业为什么不做,所以在座的同学呢,只会有张三站起来应答。但是呢,常识告诉我们,当我和张三说话的时候,张三站起来,我说这句话的本身,在做的所有同学都听到了,只不过呢,你们经过对比,当然我们后面讲对比Mac地址的时候,你会发现这个主机不是叫你,所以你就直接不做应答,只有张三主机做应答。那么在一个封闭的教室里面,我在说话的时候,你有可能也想说话,那怎样保证我们冲突的概率变低呢?其实很简单,就是我可以说话,但是我每次说话都说短一点,不像一说就会说二十分钟,因为在这二十分钟内,每一个人都想说,但是,如果每次说话,我只说一秒钟,那么这个时候和大家冲突的概率就大大降低了。所以,在数据链路层呢,在局域网通信的时候,为了尽量减少冲突呢,它有一个硬性规定,就是在数据链路层转发数据时,我们数据链路层,所能承担的数据呢,最大能够发送的单个数据量大小呢,它的有效载荷叫做MTU(MAX_TRANSIMIT_UINT),这个概念呢,我们后面还会再说。
》今天要告诉大家一个基本事实,我们的网络层,你想向下交付报文的时候,报文是有大小约束的!约束是多少,为什么要有呢?我们后面会谈的。反正就是,你网络层要有一个3000字节的数据交付给链路层,数据链路层就会说,这个3000字节的报文呢,我不能够给你转,你必须将你的报文呢,分成两个部分,然后我给你分装成两个数据帧,你将来是两个数据IP报文,这个时候我才能够给你转,否则我就无法给你转,这就叫做我们对应的数据链路层有最大传输数据的规定!
》我们的结论出来了,我们的数据链路层有单个数据帧的最大值约束,所以,我们不能发送太大的IP报文。那么就有一个问题,我们不能发送太大IP报文,大小由谁控制,我们后面会说,其实它和传输层也有关系。现在呢,我知道一个事实,如果我的IP报文很大,那怎么办呢?这里就涉及到一个叫做,IP分片的问题。
》下面将一个小故事,帮助大家理解一下。我今天有20本书,我想将这20本书送给我的朋友,这20本书一称重发现是10公斤,顺丰呢就跟我说,你好,我们顺丰有一个规定,当个包裹的重量不能超过2公斤,所以你这些书呢,我需要将其打包成5个包裹,然后再发出去。然后,我说,行吧,就拆吧。然后,顺丰又说,我们也有规定,我们不能替客户,将超重物品进行拆分。今天是10本书,拆的话很好拆,但是,你如果抱来一个台式机呢?它如果也超重了呢,那么顺丰公司是不能拆,万一拆坏了呢?所以得你自己拆,拆完之后,在顺丰看来是5个包裹,所以只好将我们的10本书拆开成2本为一个包裹。其中,顺丰呢,就相当于我们的数据链路层,我们有发送包裹的需求呢,那么就相当于是IP报文。这个呢,不是重点。
》重点是,因为我们底层规定数据报有上限,所以IP报文不能够太大,不能太大怎么办呢?所以,我们要对IP报文进行拆包,拆包的时候,我们就需要花一点时间,将其拆成若干个报文,但是,当你在拆的时候,你是不是还要考虑未来组装的问题。请问大家,如果今天想发送一个比较大的报文,将报文交给数据链路层,链路层有这个规定的话,其中,我们第一个问题是,在我们看来,如果数据报太大,我们需要对IP报文进行分片,也就是分成若干个数据报,专业点叫做分片。但是分片是由谁来做的呢?这个分完片的报文呢,被对方全部收到之后,由谁来组装呢?
》我们现在知道,链路层有最大数据报大小传送规定,然后
分片是由发送方的网络层来进行分片
。我们现在有一个基本事实是,就是,我们数据链路层,它规定了一次最多能够发送数据的上限,上限是多少还没谈,然后网络层如果发的一个IP报文太大了, 那么此时这个分片工作由谁来做呢?答案是:由发送方的网络层。网络层原本要发送一个很大的报文,现在要拆成若干个报文,然后分别交给链路层来进行发送。
》第二个问题,如果最终对方的数据链路层鞥收到了若干个报文,当然还有其他报文。 你数据链路层将报文收到了,它最终也要对数据做组装,组装由谁来做呢?谁污染,谁治理;谁分片,那就谁组装。我们数据报被批量的发送给对方之后,一定是由对方的网络层来进行组装。换句话说呢,我们传输层将数据交给网络层后,IP报文也可能发送的数据太大,然后网络层会自主地帮我们进行分片和组装。说白了就是,网络层要帮我们分片和组装。
》第三问题,**无论是发送方还是接收方,分片和组装的行为,双方的传输层需要知道吗?就是网络层万一进行了分片,到达对端然后进行组装,你们双方的传输层知道你们能分片吗?答案是:它们不知道,而且他们也不需要知道,更加不关心。**为什么呢?这就叫做,协议栈之间,每一层的功能要进行解藕。你网络层进行分片,那你网络层进行组装,和我传输层有半毛钱关系吗?我不管,我给你的数据是一个3000字节数据,对方拿的时候,只伸手向你要3000字节,你是否分片,怎么分片,我压根就不关心。这就特别像公司的老板,今天有一个市场人员,老板就说,你是负责市场部门的主管,不要给我说原因和理由,我今天就告诉你,你必须得把营业额做到1000万,这就是传输层传达的任务。接下来销售的主管,具体为了达到1000万,怎么做,完完全全就是由他自己决定,他是自己将业务做好,还是交给其他人,老板不用管,反正就是网络层帮你做了,这就叫做,功能上解耦。
》换句话说呢,我们数据在进行分片的时候呢,我们传输层不关心,可是,很显然,如果我们向网络里面发数据,以前只需要发一个报文,现在因为一些链路层规定,导致我网络层呢,要将报文进行拆分,拆成3个报文,因为,传输层不关心你的分片,如果我们网络层将来收到了若干个报文,它要进行组合,就有可能会出现组装不起来的问题。换句话说呢,对方发了3000字节,到我这里只有2800了,此时该报文能不能交给传输层呢?也就是说,分片之后,其中有一部分报文出现丢失了,一个完整的报文有3000字节,到达对端主机后,这个完整的IP报文有一部分丢失了,会不会向上层传输层交付呢?答案是:根本就不会。不会的话,那么问题怎么办呢?一旦分片之后,这个完整的IP报文当中,只要有一片丢了,那么整个的IP报文就认为是整体丢包了,无法向上层交付,那么在我们的传输层看来就是,丢包了!换句话说呢,就相当于,如果你网络层直接给我分片了,分片当中,有一个分片报文丢失了,那么对不起,到了对端装不起来就玩大发了,此时就要将报文作为整体直接丢弃的!
》同学们,应不应该这样呢?答案是;肯定是应该的 。因为,传输层根本就不知道你出现了分片,传输层交给你网络层的报文,是一个完整的报文,所以,我只对这一个报文进行丢包重传,你自己决定分片,然后导致丢包了,那就是你的问题,丢包后,大不了我再给你重传给你。
》事实告诉我们,今天在网络里面传送一个报文更容易丢包呢?还是传送三个报文更容易丢包呢?因为,三个报文里面,任意一个报文丢了,那就是整体丢了,那丢包概率是不是大大增加了!所以,在网络通信当中,我们网络层进行分片不是主流,我们未来争取我们的网络层不要进行分片,因为一旦分片,很容易出现丢包问题,丢包概率增加了嘛。所以,我们为什么要做这种吃力不讨好的事情呢?所以,我们一般发报文的时候,我们后面会进行协商,让我们的网络层尽量的不要进行分片!当然怎么让网络层不要进行分片的问题呢,我们后面在谈网络和传输层之间的关系会谈到。现在,我先告诉大家,这个网络层分片呢,不是主流,尽量不要进行分片,怎么做到不让它进行分片呢,我们暂时还回答不了,后面再说。
》下面的问题就是,我基本清楚了,你想告诉我的就是,传输层将数据交给网络层,网络层你自己自由处理数据,因为数据链路层有自己的规定,你有可能分片,也有可能不用分片,尽量不要分片,如果你分片了,那么你最终在对端组合就行了,组合完后,我交给网络层是一个报文,对端网络层交付给传输层也必须是一个报文,其中出现一个分片丢包,那么就是整体报文丢包了。所以呢,我们尽量还是不要分片。
》当然,大家肯定还有问题,就是我网络层进行分片了,我分片之后,如何到达对端主机进行组装呢?所以,就有了IP报文的第二行字段!第一个问题就是,你说了,因为底层的规定,它网络层要进行分片,现在的问题是,如何进行分片呢?
》首先,我们要意识到的一点就是,当我们把一个报文,假设这个报文有3000字节, 我们要将其分成3份,那么每一片就是1000字节,我们不光光要考虑分的问题,还要考虑组装的问题。所以,这里的一个报文,我们拆成了3份,这3报文呢,在我们的报头当中都携带了一个叫做,“16位标识”字段。什么叫做“16位标识”字段呢?就是IP报文也有自己的序号,只不过呢,这个序号用作标识来使用。假设标识是1234,所以,未来拆成3份之后呢,每一份都要携带我们对应的IP报头,它们都是一个独立的IP报文,他们报头当中的“16位标识”字段,填充的都是1234。所以,当对方网络层拿到了报文的时候,我们要进行组装,我们第一步就是,将序号相同的报文先给收集在一起。也就是,你得先把16位标识相同的报文放在一起,然后你才有可能将其组装好,所以,凡是“16位标识”相同的,我们都放在一起。
》这里也有坑,想象一下,你的网络层呢,除了来自一台主机的数据,还有可能其他主机都在给你发消息,换而言之呢,我们对应的接收方的网络层会收到来自各个主机发来的消息,而且我们的IP报文呢,有的是一个报文,有的是是分片的,有的是没有分片的,所以呢,我们要将序号放在一起呢,前提条件是,你得知道该报文是被分片的!也就是,**前提要先识别到该报文是被分片的。**那么你怎么知道,比如说,我未来要收3个报文,那么,当我收到第一个报文的时候,我怎么知道这个报文曾经是被分片过的呢?我要是不知道被分片过的,我此时就直接向上交付了,所以,我们得先识别报文是否被分片过的,所以怎么做呢?
》所以,IP报头还有一个“3位标志”字段。3位标志字段内,有两个重点标志位,第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示"更多分片", 如果分片了的话, 最后一个分片置为1, 其他是0. 什么意思呢,就是如果我们的一个报文被分成了3片,如果我是第一片,我的3位标志的第三个bit位“更多分片”置1,如果我被分片了就置1,如果是三片当中的最后一个分片,那它就是置0,就跟那个字符串一样,和"\0"意义有点像。所以,最后的一个分片的三位标志的第三个bit位置0,其他的分片是置1.
》换句话说呢,当我要识别该报文是否被分片了,当我收到每一个报文的时候,我都去检测,该报文当中的报头的三位标志里面的“更多分片”是否被置1。因为,我收到报文,比如说被分成了3片,只要收到这个报文,它的”更多分片“置1,就代表这个报文是被分片过的,所以,我们要继续读取它的16位标识号,然后继续将序号相同的报文放在一起。当然,我知道大家有一个问题,就是我先收到的是3个分片当中的最后一个被分片的报文,它的“更多分片”是置0的呀,这么怎么办呢?这个问题一会儿说。
》现在还有一个问题,你的3位标志里面呢,有一个叫做“禁止分片”,这是什么意思呢?这个的意思是,如果我们的IP报文,交给数据链路层呢,如果我们设置了该bit位为1,禁止分片,那么就是不想让网络层给我们进行分片,该报文呢,就会被该主机直接丢弃,也就是说么,我们关闭掉了它的分片功能。一般我们的“禁止分片”的标志位呢,我们也是不怎么打开的,就相当于我们把“禁止分片”打开了,如果超过了数据链路层规定的数据大小,它不是分片策略,而是直接将报文进行丢弃,这就叫做“禁止分片”。
》所以,3位标志当中,值得学习的就只有一个,表示的是“更多分片”。只要被置1的,表示的含义就是,我后面还有分片,你再等一等,只有这个位置为0,表示的是当前呢,已经没有该报文的分片了。然后呢,我们现在能够识别出来IP报文当中,哪些是被分片的了,主要是查它的3位标志当中的“更多分片”,只要是置1,那就是被分片的。是分片的,那么就再提取报头当中的“16位标识”字段,再把未来收到的IP报文序号相同的放在一起,那么接下来要考虑的就是,如何正确组装?
》那么还有一个字段就是“13位片偏移”。说白了就是,我们一般情况下,你是一个独立的报文,那么3位标志字段的“更多分片”是置0,16位标识是0,13位片偏移也是0。但是呢,你如果分片了,每一个分片都是独立的IP报文,所以也有自己的报头,所以,它呢,也是需要设置自己的13位片偏移的。举一个例子,这里有一个3000字节的iP报文,被分成了3片,每一片都是1000字节,那么第一片报文当中,它的13位片偏移就是0,第二片报文的13位片偏移被设置就是1000,代表的是该报文在原始报文当中,距离起始位置的偏移量,那么在下来一个,第三片报文的13位片偏移量就是2000了。所以,当我们收到这个报文的时候,非常简单,我只需要根据,我所收到的所有,根据13位片偏移,从小到大排序,就将所有的数据报组合起来了。
》我们先将主体讲出来,然后再缝缝补补我们的知识。所以,大家一想就能想通,第一,你这里有一个3位标志字段,如果“更多分片”位置被置1,那就是你这个报文是被分片过的,那么我就先不急着向上交付,后续收到同样的16位标识的报文放在一起,然后再根据13位片偏移进行排序不就好了嘛。你想这么简单,但是这里会有非常多的问题!
》第一个问题,你要先识别到对应的报文是被分片的,我们说了,不是有3位标志字段嘛,然后里面有一个“更多分片”的bit位,如果被置1,就代表是被分片过的,然后在后面还有分片报文,所以,只要识别到了1,就知道报文被分片过了,这个还是比较好理解的。但是在网络当中传送数据的时候,它是乱序到达,至于传输层才能保证最后能够按序到达,网络层能够保证收到的3个被分片的报文,先收到的是第一个分片报文吗?如果先收到最后一个分片报文的时候,它的“更多分片”bit位是置0的呀,你怎么识别出来它是分片的呢?我们能做到吗?答案是:能!因为,如果你的“更多分片”bit位是置0,那么假设你没有分片,那就还好,如果你分片了,那么你一定是分片报文的最后一个。如果你是0的话,那么你的13位片偏移一定不是0!
》所以,第一个问题,我们要补充的知识是,你怎么识别到该报文是被分片了的呢?原因就是,判断条件是这么写的,if(“更多分片”==1 || “更多分片” = =0&&“13位片偏移”!=0),如果符合,就证明你是被分片的报文。
》第二个问题,我们先将序号相同的报文收集在一起,最后我们再组装,但是,这里又有一个问题,收集的时候,你怎么保证你收集完了呢?我一旦识别到你是分片,我怎么保证我收集完了呢?收集完的依据就是,只要我收集的一批报文里面,绝大部分报文的三位标志中的“更多分片”是置1的,那么如果有一个是置0,那么代表我把报文收集完了,注意收集完了,只是一种说法,我知道大家也有问题,换句话说呢,我们在收集的时候,我们只要根据更多分片为1 的留下来,直到我拿到是置0的,那么我就收完了,但是,收完并不代表你收全了。
》接下来,第三问,现在你有方法来保证你将其收完,说白了就是,您能够保证你收第一个的报文“更多分片”是1,那么片偏移是0,最后一个分片报文的“更多分片”是0,片偏移不是0,我能够保证我收到了开始和结束了,但是你能够保证你收全了吗?**你怎么保证你收全了呢??**我们想一想,如果中间有报文丢失呢?你不是分片了吗?如果第一个丢了呢?中间的丢了呢,最后一个丢了呢?我怎能够保证我收全了呢?也是能够保证的。假设是第一片丢了,我收了一批报文,最后也收到了最后一个分片报文,其“更多分片”是0,假设第一个丢了,能识别出来吗?我们经过排序,发现呢,排序完后的最小片偏移不是0, 那就证明我们的第一个分片报文丢了;如过是最后一个丢了呢?很简单,如果我们一直没有收到“更多分片”是0的分片报文的话,这个也是能够知道。我们最担心的是,如果中间的丢了呢?中间的丢了,能够识别出来吗?能!为什么呢?经过排序,我们只有2个报文,第一个报文片偏移为0,加上自身的长度,就是下一个报文的起始偏移量。我们当前任何一个报文,它自身的片偏移 + 自身的报文长度,就是下一个报文的起始偏移量,如果我们今天中间丢了,其实偏移量为0,加上我自己的长度是1000, 那么下一个报文的片偏移应该是1000,可是排完序之后,下一个报文的片偏移是2000了,那不就是有报文丢失了吗?所以,我们也能够通过片偏移 + 报文自身长度来判定中间报文是否丢失的情况。
》所以,无论是,第一个丢,结尾丢,还是中间丢,我们都是能够识别出来。又有人说了,那如果我们丢了不止一个呢?能识别到吗?一样的方法。只要我们想判断是否为连续报文,很简单,排完序,偏移量+自身报文长度就是下一个报文的片偏移,以此类推计算,我们就能保证,既能够将报文收完,“更多分片”是置0的,又能够保证收全,中间丢,开头丢都能识别到。所以,我们通过这三个字段:3位标志、16位标识、13位片偏移就能将我们的分片报文进行组装了!
》所以呢,我们要先识别到报文是否被分片,原则呢就是if(“更多分片”==1 || “更多分片” = =0&&“13位片偏移”!=0),然后呢再提取序号,将所有的序号组合起来,只要碰到了“\0”就是“更多分片”是0的分片报文就表明我们收完了,但是呢,这个收完得换种说法,但是至少证明我们收到了最后一个,然后我们进行排序,排序的时候,开头、中间、结尾丢我们都是能够知道的,然后我们讲完整的分片报文组合起来变成一个报文交付给上,至此我们就完成了组装交付的工作。
》所以,我们网络层分片分什么呢?它将把一个完整报文拆成3个之后,就要给每一个报文的报头里面填充3位标志、16位标识、13位片偏移,填充好后,就可以被对方收到,然后再进行组合。其中,分片和组合的行为是网络层自发的行为,传输层根本不知道。
》至此,我们将IP报文的报头字段全部讲完。最后再说一个问题,有时候我们在进行分片的时候呢, 我们也要保证组合好的报文是符合我们预期的,所以,最终我们也要有16位首部校验和,合并好之后呢,可以通过校验和来校验数据,尤其是报头字段有没有问题。因为,分片组装呢,最重要的不是数据出问题,而是标志位出问题,所以,它要有16位首部校验和。有人说,它怎么不对整个报文做校验呢?对整个报文做校验,第一是太慢了;第二是没必要,因为TCP和UDP也有自己的16位校验和。所以数据真的组合起来,报头没有问题,但是是数据本身有问题, 也会在传输层当中被识别出来,大不了丢包重传。
》下面呢,我们知道如何分片和组装,但是我有一个问题,你网络层进行分片了, 你告诉我分片是不利于网络传输的,因为一个报文丢包和三个报文任意一个丢包,很明显后者丢包的概率更大,所以我们一般不建议分片,如果分片了,这个时候,我们对TCP和UDP有影响吗?
》所以,我们来谈下一个话题,分片对UDP和TCP有影响吗?答案是:当然有。首先对TCP和UDP而言,对上层传输层而言,统一的影响,都是增加了丢包的概率。增加丢包概率呢,对TCP来说,影响倒不是很大,因为TCP有可靠性,所以,如果你丢包了,也不影响,大不了我再重传一下。但是对于UDP影响就特别大了,因为UDP呢是不可靠的,数据交给IP它就不管了,IP对报文进行分片了,然后到达对端,如果分片出现丢包,你分片引起的丢包概率增加,那么IP分片会直接影响到我们的UDP,换而言之你丢包了,你iP分片的成本吗,或者IP分片导致的问题多,最后会直接影响到UDP ,当然重传也不是什么好事情,所以无论是TCP还是UDP我们都不建议分片,所以,网络分片呢,不是主流,但是它的设计方案非常优秀,它只用了3个字段就完成了分片和组装的过程,值得我们去学习和借鉴。未来我们在应用层,做项目的时候,这个项目在进行传送的时候呢,有可能要对大块数据进行切分,那么你可以参照一下IP的做法,你也可以定义一个报头,报头里面有3位标志、16位标识、13位片偏移,你可以对齐进行分片和组装,所以它值得学习,
》那么你说网络分片不是主流,**怎么做到让我们尽量减少分片呢?**有人说,我直接不让它分片,这种做法太独断了,万一传输层交付给网络层,超过了数据链路层规定的大小,最终无法进行传送,这个锅谁背呢? 那是不是就无法传了,也就不发通信了。所以现在呢,我们是既想要通信,也不想要传输层交付较大的报文,引起分片而导致丢包概率变大,怎么办呢?我们为了让其减少分片,是由我们网络层决定的吗?**网络层是否分片是由网络层决定的吗?**答案是:不是!有人说,我都网络层来负责分片,还不是由我来决定吗?当然不是, 为什么呢?你分片是因为数据量太大了,你作为网络层,你只是一个办事的,说白了,数据什么时候发,发多少,由传输层决定,你网络层就是一个跑腿的,是否分片不由网络层决定的,所以分片由谁决定呢?对不起,不能由你网络层决定。是否分片,说白了就是你的数据量多少来决定,**是由传输层决定的!**你传输层交给我网络层的数据不要太大了,那么我网络层不就不用分片了嘛,而且,你传输层是决定数据什么时候传,传多少,怎么传的问题,所以,你传输层尽量不要给我交付的数据太大,那我是不是就不要分片了呀。所以,传输层不仅仅的要考虑对方的接收能力,也不仅仅要考虑我们网络拥塞的问题,传输层还要考虑尽可能的减少丢包,所以传输层一般在传输数据的时候,也有自己的一般大小,这个大小我们在后面会谈到。
在这里插入图片描述
当我们在进行我们数据转发呢,应用层把数据拷贝给传输层,然后什么时候发,发多少都是由传输层决定,所以,它把数据添加报头交付给网络层,然后网络层进行我们前面所谈的数据转发的问题,然后经过网络到达对端。
》其中,传输层将数据交给网络层的时候呢,数据链路层就不高兴了,它说,我传送数据是有大小规定的,我单次传输数据的上线为MTU,也就是网络层将数据交给数据链路层是有要求的,如果超出了规定的要求的呢,就要倒逼网络层将IP报文进行分片,数据到达对端的时候,在对端的网络层再进行组装,所以就有了分片和组装的概念。
》下面呢,我们假设我们的MTU=1500,也就是说呢,数据链路层接受数据的大小是1500。下面给大家举一个例子,量化一下我们的分片和组装,怎么个量化法呢,就需要给大家说一下,不说也可以,但是这里有坑,要给大家交代一下。
》假设传输层给网络层2980字节,网络层呢,IP报头标准大小是20字节,假设网络层现在有3000字节,它这里面呢,是包含传输层交给他的2980字节,然后就是IP报头的标准20字节。所以现在,网络层就要将这3000字节交付给数据链路层,现在链路层就不乐意了,你现在要转发数据,对不起,你能交给我的最大数据大小是1500字节MTU,这1500字节呢,最终作为数据链路层的有效载荷,但是这1500字节是包含了IP报头的,所以,你现在交付给我3000是传不了的,你得将3000字节进行分片。
》那么这里该怎么进行分片呢?那么就是20 + 1480—第一个1500,接下来的3000字节还剩下多少字节呢?是不是还剩下1500字节呀,接下来我们能不能将1500字节直接交给下层呢?是不能的!因为我们这里要给大家强调的是,**分片之后,每一个分片也是一个独立的IP报文,也要自己的独立IP报头!**有人就会觉的,你不是原本传输层交给你2980字节,然后加上IP报头20字节,也就是3000字节,你第一次分片,切走了1500字节,那么剩下的1500再直接交给我们的数据链路层就不好了嘛?不对的!不能这么说,我们的第二个分片报文应该是额外要加一个IP报头20 + 1480 = 1500字节,其中有效载荷是网络层剩下的1500字节中的1480字节,还剩下20字节的有效载荷没有发出去,所以此时要有第三个分片报文:20 + 20 = 40字节。那么有人说不对呀,1480 + 1480 + 20 = 2980字节的有效载荷呀,我们网络层原本有3000字节的有效载荷呀,怎么会少了20字节呢?不要忘了,传输层交给网络层的有效载荷是2980,到网络层添加了自己的IP报头标准20字节,才是2980 + 20 = 3000字节,所以,你真实要传送的有效载荷就是2980字节,所以1480 + 1480 + 20 = 2980字节,是对的!也就是说,你要网络层传送一个3000字节,其中是携带IP报头的大小,你的有效载荷是2980,你要将这么多的数据传出去,一共加起来是3000字节,那么其实,你是要分成3个报文的。我在强调一下,我们说的3000字节是涵盖了到网络层要添加IP报头标准20字节的,传输交给我的就只是2980字节,为什么一直要强调这点呢?因为我们一定要清楚,你真实要传的有效载荷就只有2980字节,再加上你第一次要传3000字节时,你其实要划分成3个报文,而并非是2个,所以这个要会算。当我们将其分片完之后呢,然后就是将他们的IP报头的3位标志、16位标识、13位片偏移填等等字段充一下。所以,我们举了这么一个例子,让大家有一个量化的理解,不然就容易出问题。
在这里插入图片描述
》第二个知识点,我们前面说过,分片是有问题的,分片对于传输层是零感知的,传输层也不关心你分不分片,待会儿我们也会知道,传输层也是要考虑的。但是呢,我们也说了,传输层交给你报文,对端传输层就要收到这个一模一样的报文,换句话说呢,你网络层将报文分成了三个,到对端网络层必须得组装好在交付给传输层,这没有问题,我们也知道,分片太多了会引起丢包,因为报文变多了,一个任意分片报文丢失,都会导致组装失败,那么整个报文也就会全部被丢弃,它只会增加丢包概率。
》所以呢,我们现在的问题是,如何做到尽量不分片?前面我们也说了,分片本身不建议作为主流,但是有时候不分片也没办法,所以只能做到尽量不分片,那该怎么做呢?这个由谁决定呢,我们也说了,首先不是由网络层决定,它只是一个跑腿的,你网络层做好你数据转发的工作,至于你网络层转发的数据量是否符合数据链路层的要求,是由我们传输层决定的,所以呢,是由传输层决定!传输层给你多少数据,你就得给我转,底层有要求,你自己给我想办法。传输层将数据派发给网络层,然后网络层和链路层协商能不能让我多传点,链路层说,不行!我的硬件规定了,一次只能传1500字节,那你现在要给我发多余的数据,你去和你的领导商量吧。那么,网络层没有办法,只能给传输层说,你不能一次给我的报文数据量少一点,不要太大了,让我分片,不然只会增加你的工作量,丢包了你只能重传。传输层说,行。所以,我们一般呢,在传输层层面上,**进行我们的三次握手的时候,就会协商单次传输数据报文的大小!**给大家留一个问题,一会儿我们后面就解决,那么传输层单个报文的大小一般设置成多少合适呢?把这个问题放在这里,稍后再来给大家解决。首先呢,你也不用担心,网络协议栈当中的问题,别人早就解决了,如果你没有解答问题呢,肯定是没有找到答案。记住了,传输层在三次握手的时候,其实就会协商单次报文的大小,从而不让网络层和链路层太难堪了。如上就是我们的预备工作。

接下来我们要进入下一个话题,就是网段划分。首先,我们要对IP地址又要来一个概念,前面我们下过一个定义是,IP是一种A主机跨网络将数据送到B主机的能力。真正的数据报在转发的时候就是IP报文,后面再带着一个Mac帧,但是传输层呢,我们以前学的相关策略,对不起,它并不在网络里面体现,传输层更多体现的是一种策略,真正在网络里面跑的是IP报文,IP既然提供了这种能力呢,为了100%让它做到,就必须得有TCP。
》然后呢,我们IP是如何找到对方的主机呢?? 1.IP的构成;2.网段划分
》我们的IP构成是 目的网络 + 目的主机。根据我们目前学到的知识呢,我们知道,IP地址是4字节,以前我们在学套接字的时候,需要将字符串的点分十进制风格通过函数转化成4字节的IP地址。比如,FF-FF-FF-FF,这就是4字节IP地址,每一个FF相当于一个字节。实际上呢,我们不要IP当作整体,IP前半部分我们称之为,目的网络,后面有部分我们称作目的主机。
》为了能够更清楚的阐述它呢,我给大家讲一个故事,然后帮助大家去理解目的主机和目的网络概念。假设在计算机学院的软件专业,我们都知道每一个学生都有自己的学号,学院啥的我们不管,其中10表示的是计科专业,11表示软件专业,其中软件专业有4个班10表示2班,03代表班上的3号,即xx111003前面的xx先不管。那么现在在路上捡了一个学生证,学生证是以xx开头,然后你对自己学校的学号划分非常清楚,然后你就知道xx后面两位代表的是专业,然后后面两位是班级,此时你就很快的拿着xx1110甄别出来它是软件2班的,你将学生证给别人还回去,然后跑到他们的宿舍楼交给班长,那么班长呢,就可以找到这名同学了。所以呢,在学校里面,我们的学号不是随便划分的,我们的学号本来就被划分成了,先将你定在某个群体当中,然后再从群体里面找到你。
》所以,我们就可以用这种方式来将IP地址等价于我们的学号,可以根据我们的IP地址当中的,我们叫做目的网络就是定位到某个网段,一旦定位到你在某个网段,然后再从网段里面找到你这台机器就可以了。这就是我们IP进行路由的基本原则。所以呢,我们在这里要给大家说一下,IP在进行路由的时候,在路上的时候,是先根据目的网络进行路由,找到目标网络之后,然后再根据目的主机的主机号在进行数据转发!
在这里插入图片描述
》IP地址分为两个部分, 网络号和主机号
·网络号: 保证相互连接的两个网段具有不同的标识;也就是在我们互联网当中,我们先不考虑局域网的问题,每一个网络都必须有自己唯一的标识,这就叫做网络号。
·主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号;就好比你在计科1班,软件3班,你们学号前面若干位一定是一样的,也就是说呢,我们将来是要把专业号相同的学生放在一起,或者班级号相同的学生放在一起,此时就可以再去根据班级里面不同的编号就可以把你区分出来了。
在这里插入图片描述
》所以,IP地址分为两部分,一个是网络号,一个是主机号。就比如图中,192.168.144.10和192.168.144.11,它们其中的网络标识是一样的,但是主机号是不一样的。所以,在同一个网络内,无论是在家中还是学校里面,只要你跟你的父母或者朋友连的是同一个网络,你们的网络标识必须一样,但是,你们的主机标识一定是不一样的。然后呢,我们在图中发现,不同的两个网段,都存在一个主机是10号主机,但是他们前面的网络标识并不一样。
》所以,换句话说呢,我们所谓的网段,其实说白了就是,网络标识相同的主机的集合,就叫做网段。那么另外呢,我们也知道,我们路由器需要负责在不同网段之间进行数据转发,那么它要在不同网段之间进行数据转发的前提是,它要集连两个不同的网络。所以路由器至少要有两个网络接口,配上不同的IP地址,所以路由器可以配两张网卡,所以,它就以192.168.144.1来标识自己和192.168.128.1用来标定在局域网当中的某一个特定的路由器。所以,所有人一旦发现,有了网络标识,那么这台主机想要转发数据报的时候,在主机内部进行路由时,把你的目的IP提取出网络标识,在做对比,发现你要去的网络不是自己所在的网络,比如说你要去的网络标识是192.168.144,所以,它的数据报在进行路由的时候,就会发现这不是要发给我们局域网内的某一个主机,它就不管,它虽然无法知道192.168.144的子网在哪里,但是知道不是自己所在的网段,那么它就可以将数据交给路由器了。因为路由器获取的信息,比局域网内或者的信息更多,只要把数据交给路由器,那么路由器就有较大的概率把数据继续向后转发。所以,对我们来讲呢,我们就以这样的网络标识符设置,以及网段划分的策略呢,来保证我们的网络内容,这是其一。
》我们刚刚谈的是什么呢?谈的是IP的构成,下面回过头再继续。按照你的说法,我们在学校每一个人都有自己的学号,我们就可以根据学号快速的找到某一个人。因为学号前面一部分内容呢,就可以确定在哪一个班级里面,知道你在哪个班级里面了,就能根据班级里面的标识符信息找到学生。可是,大家想一想,你凭什么能用这个学号呢?你能用这个学号,是不是曾经学校对我们上万名学生的学院、专业、班级做了很细的划分。给计算机学院和经管学院等,不同的学院都给了不同的标识,然后在学院内部,给不同的专业又有不同的标识,这个工作是学校在你还没有进入大学之前,早就规划好了的。只有学校把学号这个体系规划好了,然后你是不是才可以用IP地址去学校定位某一个人呀!计算机网络也是这样。那么IP划分成,目的网络和目标主机,所以,怎么样能够在全网中,根据目的网络找到目标主机,再根据目的主机,在一个网段内找到某一台机器。前提条件是,**曾经已经有角色已经将我们全球的IP进行地址划分。**说白了,就如同,全球网络就相当于我们学校,在我们使用IP之前呢,我们已经对所有的IP地址做过划分。
》我们来谈一谈历史上的划分方案,将划分方案全部讲完之后,我们再带大家重新理解一下。我们前面说了IP的理解,我们再来看看网络。
》过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示(该图出 自[TCPIP])。
在这里插入图片描述
我们以前B类用的多,什么意思呢?这个分类呢,大家可以仔细观察一下,首先这个分类就如同一块蛋糕,它也是资源。这个资源呢,又有上限,只有2^32个 ,所以就有很多的人呢和标准化组织要对IP进行划分。所以A类和其他相比呢,第一个bit位为0就代表A类,剩下的其他类第一个bit位都是1.就相当于,我把一半切走了,那么剩下的一半呢?B、C、D、E你们自己分。然后B类说,我也要切,第一个bit位已经被抢走了,只能是1,那么它将第二个bit位设置为0,那么10开头的就是B类的,那么剩下的C、D、E第二个bit位就只能是1了,然后C类对IP地址再进行划分,同样的方式划分。所以就根据IP地址不同的bit位就将我们的网络分成了5大类,然后这5大类就可以被不同的人和国家使用。
》接下来,其中A类的7位作为网络号,剩下的24位作为主机号。 B类呢,以10开头,然后以14位作为网络号,16位作为主机号,以此来看。 不同的国家、地方、机构就可以在A、B、C、D、E类认领不同的IP地址。比如,比特认领了B类,那么就是10开头,但是B类申请的机构特别多,所以B类呢,可以被2^14不同的机构所认领,比如说比特就拿到了一个,然后要搭建自己内部的局域网,怎么办呢?那么一个局域网最多有多少台主机呢,那就是2 ^16 -2个。
》我估计大家也不会很好的去理解它,这个也是正常的,也不需要担心,因为大部分教材都会这么去说,可是这里给我们带来的困扰可不止一个呀,这上面的问题还是比较多的,我们后面会讲一个例子。就相当于,我们全球呢将IP资源划分了,划分了之后呢,随着网络的发展,IP地址本来就已经严重的吧足了,比如说,我们大部分的组织,其实IP地址是一种资源,国家和国家之间对IP地址是有竞争的,我们国家伴随着信息化发展呢,很多IP地址都被美国或者欧洲国家拿走了,那怎么办呢?我们国家在花大力气搞IPV6。
》比如说,美国或者其他机构都想要A类IP地址,A类太少了,它只允许2^7机构来进行认领。那门比如申请B类,那就会导致B类很快的就被申请完了,拿着B类以10开头,然后申请网络号,一共允许2 ^14个人进行申请,这里的16位主机号什么意思呢,就是B类可以构建的最大局域网,这个局域网内的所有主机号的网络号都是一样的,但是呢,一个局域网内只允许2 ^16台主机。但是呢,大部分机构申请了这么大的一个局域网,它的局域网主机可能就用不完。比如说,我们国家有一个机构,它这个公司内部最多用2万个IP,也就是它的局域网当中呢,最多有2万台机器,但是呢,B类的一个局域网可以6万多个用,你却只用了2万,这个B类一旦被你申请了,那么这个网络呢,就不能被其他机构用了,换句话说,这个IP地址你只用得到2万,其他的4万就被浪费了。所以呢,大部分组织和机构都申请B类,导致 IP地址被分配完了,我们都知道IP地址非常不足了,你还在这里浪费,那怎么办呢?
》就提出了下一个方案,这个方案就是CIDR。CIDR的方案做法更加灵活,它使用了一个,每一个字网都必须配上一个子网掩码,用子网掩码来区分网络号和主机号。举一个例子,我们以前在划分的时候,前面的若干个不同的bit位就可以标定不同类型的IP地址,然后再用前面几个bit位来区分不同的网络号,这个工作就相当于编址的过程,不同的网络,它的网络号一定可以做成不一样,但是就如我们所说,IP资源已不足了,不能进行浪费。所以呢,我们就引入了子网掩码。
》假设我们现在是1101 0101,其中呢我们可以引入相同位数的子网掩码,假设我们以8位为例子,假设我的子网掩码是1111 1100,即1101 0101/1111 1100,其中呢,我想提取1101 0101,也就是IP,这个IP呢等于目标网络+目的主机嘛,所以,如果我有一个IP的话,我想计算出这个IP地址最终标定的目标主机的网络号是多少和目的主机是多少了,那么我就1101 0101 & 1111 1100,也就是IP和我们的子网掩码进行按位与&运算来提取网络号,那么按位与&之后,结果是1101 0100,那么其中我们可以发现我们的网络号就是1101 0100这个样子的。这个网络号就相当于呢,把表示主机的bit位全部清0,剩下的就是网络号。所以,用这样的数据,即子网掩码,就可以动态去调整我们的网络和主机号,用1的位数,你如果想让主机更多一些,把这个子网掩码的一些bit位置0,那么就可以有更多的主机了;如果你想让主机号变少一点, 那么就让子网掩码中的bit位为1变多一点。
》所以就可以通过子网掩码的方式,动态调整我们IP地址中对应的网络号和主机号。也就是说呢,我们·引入了IP和子网掩码的概念。
·引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
·子网掩码也是一个32位的正整数. 通常用一串 “0” 来结尾; 将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号;
·一旦有了子网掩码呢,网络号和主机号的划分与这个IP地址是A类、B类还是C类无关
》如上就是我们的网段划分的方式,我们目前呢,不再采用这种分类划分法了,它是历史的产物,我们在全部都是采用的子网掩码的方案。这个子网掩码呢,一般都会被配置进路由器当中,这个路由器呢,会根据子网掩码,不断的进行按位与&运算来确认你要去的目的主机是谁。
》不要着急,在我们继续往下谈之前呢,我们重新回过头再谈一谈网段划分,这次谈呢,就尝试着让大家理解它了。上面呢,是常识知识,很多教材基本上就这么说了,但是,上面说白了就是数学问题。那么这里,我有很多问题,比如说,你先是给我们说,有了IP的构成,然后我们就可以根据目的网络和目的主机找到确定的人,没问题,人代表主机,主机找到人就找到了。 可是在我们进行使用我们自己学号的时候,一定是学校曾经将学号的体系建立好,上学之后就自动给我们分配了,现在的问题是,数据报在网络当中进行路由的话,要使用IP地址,是不是已经曾经有人把全球的网络给建立好了,是这个意思嘛?是的。
》下面,我想给大家举两个例子,第一个例子就是,我们还是以学校为切入点,比如我们每个人都在自己的学院,比如计算计学院有自己的群,如果学校有10个学院的话,每一个学院是不是都有自己的群呀。然后呢,我们学校有这么一个概念就是,学院有院学生会主席,我们学校呢,还有校学生会主席,一般学院的学生会主席要去参加校学生会。这个道理就像呢,有一个计算机学院的群,它有一个院学生会主席,同时呢,每一个学院的院学生会主席都在一个群里面。假设学校的学号是8位前四位标识学院,在后两位是专业班级,最后两位代表的就是学号代号。假设我们的计算机学院的编号是0001,理学院0010等等以此将学院编号。有一天你在路上捡到了一个钱包,钱包里面有一个学生证,里面有一个学生的学号,学号是1000 1101,当你捡到学生证的时候,你要把钱包交给某一名同学,那么其中你就有两种做法,第一种做法呢,有的同学比较执着,怎么个执着呢?每天早上6点起来,在校门口逮住一个人就问,你是不是1000 1101的同学,在找的时候呢,可能过了一两年,这个学生都毕业了,都没能够找到该学生,这是第一种,当然大部分学生都不会这么做。因为大家都知道,首先我知道1000 1101肯定不是我们计算机学院的,我们计算机学院的是0001开头,同时我还知道,我只要将这个学号扔到计算机群里面,然后我们院群里面的学生会主席不就是从事学生工作的嘛,那么他是不是可以帮我去找呀,学生会主席拿到之后,他就是搞学生相关的工作,他清楚地知道这不是计算机的,假设就算是学生会主席业务能力不强也不知道是谁的, 但是他有对应的校学生会主席群,然后对比之后,就知道1000不就是经管学院的嘛,那么学生会主席将丢失学生的学号扔到校学生会主席群里面,然后@一下经管学院,然后经管学院的主席就知道是他们学院的学号,然后经管学院主席提取后两位专业班级,然后就可以确认是哪个专业哪个班级,然后经管学院主席是不是也有自己学院的院群呀,然后就将学号信息转到经管学院的群里面,然后就可以接@一下01号同学,最终呢就可以把物品交给对应的学生了。
》这个工作呢一两个小时或者几分钟就能将信息转成功了。这是一个非常简化的模型,但是这个模型想告诉大家的是,当我们在进行入校的时候,我们的学号呢,早就被编好了,每个学院有什么编号,早就被编好了,所以,当我们有学院编号之后呢,我们就可以直接使用学院编号来互相去定位某些学院,其中,经管、理学院、计算机学院等就相当于子网,具体的某一名学生就相当于子网内的某一台主机。我们例子当中捡到的钱包,钱包里面的信息呢,就相当于你一个子网要发送数据给另一给子网,这就叫做数据转发,而我们院学生会主席呢,我们就称之为路由器,其中院学生会主席之间建立的大群,我们称之为叫做,公网。
》我希望通过这个例子呢,提炼出一些结论,然后再进一步谈。下面给大家总结一下结论,**发送数据的本质,是不是就是先要找到目标主机,**就好比你现在先要把你捡到的钱包归还给经管学院的某一名同学,那你是不是得先找到他,而我们要找的目标主机呢,根据目前知道,我们要找到这名经管学院的同学,我们要先找到经管学院所在的目标网络,找到目标网络之后,知道他是经管学院的,然后再根据目标主机,就可以将数据交给他了。假设我们的学校有2万学生分散在不同的专业,你要找到目标主机,其实就是找到目标学生,找的本质就是排除过程。我们刚在找一名同学的时候,我们有两种方案,第一种方案,就是你自己一个个去问,是不是就相当于,你一个个去排除,而如果我们经过网段划分,每个学院都有自己的院号,你属于哪个学院,你将来的学生证上,你的学号就必须以他开始,将来有人想找你的时候,就直接拿着院号,直接一次就可以淘汰一大批。所以,以前如果你是一个一个的在全网当中找某一台主机,你是一个一个的去排除,而如果我们经过网段划分,划分成一个个的子网,那么我们查找的时候,就可以根据我们的子网,一次可以拍出一大批。所以,子网划分,每一个子网都有自己的标识符,我们可以根据子网的标识符,一次就可以拍出一大批的子网,所以我的问题是,我们的互联网为什么要进行子网划分呢?叫做,便于查找目标主机的效率提高。我刚刚回答的问题是,为什么要进行网段划分。
在这里插入图片描述
》实际上呢,我们IP地址在划分的规则呢,和我们在学校里面是一样的,但是我们在宏观上还是得初步理解一下他,下面我们应该怎么做呢?各国都有自己的IP地址,我们为了方便,我们中国IP就以11开头,美国是以10开头,德国以01开头,国家与国家之间的路由就构成了我们网络的结构。比如说,在我们中国有一个IP报文的目的IP是以10开头的,在我们内网转发的时候呢,识别到不是我们国家内的,通过出口路由器,查询路由表,就转发到了美国。下一个在继续,我们中国内部又可以划分成很多的省份,我们中国的IP地址都是11开头,我们有若干个省,所以各个省份的IP就是11xxxxx.这样的格式,每个省市可以再根据11xxxxx再往下划分。我们的省又可以往下划分成市,如11xxxxxyyy。就是美国有一个报文的目的IP是11 00000 0010,发现11开头的不是它美国的IP呀,所以,美国的路由器呢,就向上转发,经过美国的运营商呢,转发到出口路由器,然后在全世界的公网上面问。11开头的是哪个国家的,然后我们中国就举手了,就将报文交给我了我们中国,所以,中国再根据后面5bit位确定是哪个省的,然后是河北省的,然后再根据后续的几个bit位进行提取知道具体的市了,然后一直往下转发,最后就到了目标主机了。
》所以,在我们省跟省之间也要有大的公网呀,所以这就是网段划分。其实网段划分本质就是被全球的,根据2 ^32个地址,把IP地址划分给不同的国家,有很多国家不是都入网的,但是像美国、欧洲、日韩等入网了,然后商量我们中国11,你德国01,美国10等等,但是全世界有297个国家,所以2 ^8=256,我们就用前8位来标定国家,然后生下来的就是分给你国家内部,当然这只是简化的说法。虽然有不同的国家,但是国家内部的人口不一样。
》我们要对全球的IP地址进行编址,编完址之后,说白了,就是我们将IP资源划分完了。是不是就得有人搞基础设施。所以,我们经常在用app的时候是可以定位到你在哪个省市的,所以IP地址可以定位到你是哪个区域的,当然更详细的就没有了,一般在IP地址严重不足了,怎么可能将裸的公网IP地址全部都给我们划分到村上、区上呢,太浪费了,我们有其他策略。总之就是我们有了IP地址,那么你说转发就转发嘛?所有的基础设施在我们国家都是由三大运营商来做的。
在这里插入图片描述
》如上就是我们网段划分的宏观结构,回过头再来看一下网段划分,所以一开始我们网段划分A、B、C、D、E五大类了,比如你们大国人口多,你们就用A类,不够你就用B类,小国家你们就用C类啥的够用就行,当然不可能严格这样,这是历史产物。
在这里插入图片描述
》可见,IP地址与子网掩码做与运算可以得到网络号, 主机号从全0到全1就是子网的地址范围;
》IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68, 子网掩码的高24位是1,也就是255.255.255.0
》以上,一共回答了3个问题。第一个问题是,子网划分是什么?全球标准化组织将我们对应的IP地址划分给不同的国家,国家内部再自己自建网络设施,所以网段划分呢,是分配IP资源的一种策略。第二个就是,为什么要进行网段划分呢?原因是因为,经过网段划分可以大大提高我们的查找效率,因为将来发送到某一个国家或者省份的数据呢,可以根据前面若干个指定的bit位来确定是某一个地区的数据,一旦确定是某一个地区的,就可以将其他的全部排出,我们就可以一次排除一大堆的数据,从而提高效率,这就是为什么要子网划分。
》就光光这样讲就完了吗?当然没完,我们只是搭建了一个宏观轮廓,我们还是得具体谈一谈,实际上也说了,按照你这样划分的,到了我村上,到了我家里,用的是全球划分的某一个IP地址吗?这样划分的话,IP资源不足只会更加凸显嘛。所以我们还得去理解局域网。我们待会儿要基于公网的理解,再去理解一下局域网。

我们进入下一个环节,我们刚刚是在宏观上交代清楚了。我们在正式讲之前,给大家回答一个困惑,你说我是一个美国人,我怎么知道你中国IP地址是多少呢?同样,我是一个中国人,我怎么知道你老美的IP地址是多少呢?现实生活中,大家都知,我们不是拿IP地址做的,一般访问的时候,如www.gogle.com,都是通过域名去访问的,换句话说呢,在全球有一个域名解析,它是由一些域名组织帮我们组建的,它主要是做域名和iP的映射。所以,一个美国人想要访问中国的网站,跟不就不是拿着I P地址去访问,它是用www.qq.com等去访问的,它在访问的时候,实际上是先请求域名,然后域名解析机构,对应的有1级、2级域名,说白了就是KV映射,然后根据域名凡回应的IP,用软件的人呢,用浏览器,访问他们国内的相关基础设施,然后就把数据转发到我们国家了。所以,我们要能理解的就是,我们不用担心不知道IP的问题,它不需要知道,它是哪域名去访问的。
》根据你刚刚所讲的,这里有一个问题就是,IP地址不足,是不是整个全球的网络就是不断的子网划分下去的呢?从国家层面上划分到IP资源,然后再在省内部划分IP资源,然后省到市,市到区,区到村,再到家里面,是这样的嘛?不是的!这样划分,IP资源永远都不够,IP地址一共才42亿多,这样划分肯定是不对的。
》我们IP呢,有特殊的IP :·将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;
· 将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数
据包;这两个IP呢是一般我们在进行使用的时候呢,确定一个子网当中有多少台主机,是要减去这两个IP
·127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1;它在进行我们数据转发的时候呢,当我们使用127地址,它把我们的IP数据交给我们底层,底层进行转发,它会判断你是不是环回,如果是的话,不会将数据发到局域网当中,然后将数据放入我们的输入队列里面了,让上层拿走。相当于,如果我们使用IP呢,我们就将数据自顶向下贯穿一次我们的协议栈,然后到最底层,然后再自底向上交付一次,数据是不会在网络当中走。

我们知道, IP地址(IPv4)是一个4字节32位的正整数. 那么一共只有 2的32次方 个IP地址, 大概是43亿左右. 而TCP/IP协议规定, 每个主机都需要有一个IP地址.
》这意味着, 一共只有43亿台主机能接入网络么?
》实际上, 由于一些特殊的IP地址的存在, 数量远不足43亿; 另外IP地址并非是按照主机台数来配置的, 而是每一个网卡都需要配置一个或多个IP地址
》CIDR(子网掩码的方式)在一定程度上缓解了IP地址不够用的问题(提高了利用率, 减少了浪费, 但是IP地址的绝对上限并没有增加), 仍然不是很够用. 这时候有三种方式来解决:
·动态分配IP地址: 只给接入网络的设备分配IP地址. 因此同一个MAC地址的设备, 每次接入互联网中, 得到
的IP地址不一定是相同的;说白了就是,你如果这台机器不联网,就不给你IP地址,如果你要上网再给你IP地址。最典型的就是你连你家的wifi,你不连,你那么你手机上是没有IP地址的,你一连你路由器就会给你分配IP地址。但是这种做法推广到公网当中也是可以的,你不上网就不给你分配公网IP,但是哪个设备在公网上不联网呢?在公网上的不是路由器就是服务器,他们都是要24小时工作的,所以这个并不能解决问题。
·NAT技术(后面会重点介绍);将我们的局域网和公网之间,通过一定的转化方式,在我们能够在使用IP地址不足的情况下,依旧可以凭空变出更多的IP能够进行在子网当中工作。
·IPv6: IPv6并不是IPv4的简单升级版. 这是互不相干的两个协议, 彼此并不兼容; IPv6用16字节128位来表
示一个IP地址; 但是目前IPv6还没有普及;

我们要能够使用未来的NAT,以及为了能够进行更合理的IP资源使用,所以,我们的IP地址在自身构成上被分成了目标IP和目标主机,它在整体的结构上呢,IP也被拆分成了IP地址和公网IP地址,一个叫做私有IP,一个叫做公网IP。其中我们的RFC也叫做互联网标准化组织呢,规定了,我们的有一些IP地址是不能放在公网上的,它只能用来组建局域网或者组建子网,那么这样的IP呢,我们称之为私有IP,而除了这批私有IP之外,剩下的才能出现在公网上。
》换而言之呢,我们对应的RFC1918,它规定了哪些IP只能用来组建局域网, 就是10开头的,然后一共有16777216个地址;然后172.16.到172.31.,前12位是网络号,共1,048,576个地址也是我们的一批私有地址;还有最经典的192.168.*,前16位是网络号,共65,536个地址 包含在这个范围中的, 都成为私有IP, 其余的则称为全局IP(或公网IP);所以IP被划分成两类。
》这个太重要了,他可以帮助我们进一步看到网络的全貌。其中192.168. *xx是我们经常见到的。 我们平时用的云服务器,我查的我的是172.28,是不是在我们上面说的172.16到172.31之间呀,它也是属于私有IP,所以我们在自己的云服务器上面查出来的IP,并不是用的公网IP,而是私有IP。所以呢,我们就有了私有IP和公网IP这样的概念。而我刚刚所说的,从全球进行我们的网址划分,把IP地址划分到我们的国家,从我们国家再到省上,它们在省之间呢划分的IP地址你可以理解成就是公网的,甚至到市上,但一般到省上就够了。
》接下来我们再谈下一个话题,那么私有IP是如何解决IP不足的问题呢?比如说,腾讯的服务器呢,子啊内蒙古,你假如在云南,不影响,我们知道内蒙和云南呢,也就是省和省之间是可以通过广域网进行互相通信的。另外第二个点就是,你一定是在你的家里面,而你家里面呢,知道的话呢,比如说你家里面刚开始没有网,如果家在城镇,在盖房子的时候,网线就已经拉进去了。假设你在村里面,家里面是没有网的,但是如果周围已经有人装网了,比如说周围装的是电信的,所以你爸呢,他也想拉网,那么此时就可以给电信本地运营商打电话说拉网,然后就会派工作人员将网线拉到你家里面,把猫装上,甚至送一个路由器,然后就构建了一个家庭网络。所以,我想说的是什么呢?你们每一次所上的网的前提条件是,网线得由运营商拉到你们家里面,然后才能让你家里面上网,这是第一个问题。
》第二个问题是一个常识,你经常拿着手机刷着抖音,看着爱奇艺等等,以抖音为例,为什么天天刷的抖音,是抖音给你提供的服务,为什么交话费却交给了三大运营商呢?相当于我玩的是抖音呀,我享受的是抖音给我提供的资源,为什么我钱都交给了三大运营商呢?我们来说一下,你家里面的家用路由器是有一个功能的,他的功能是,除了进行IP报文转发之外,还有一个就是构建子网功能。所以,你家里面一上网,说白了就是,路由器装好之后呢,你就可以访问路由器背面的设置好的局域网IP,一般都是192.168.1.xxx,路由器这样的设备,在一个子网当中,通常都叫做1号主机。家用路由器呢,一般都是你自己配置好,配置好之后就可以设置你的WIF密码,别人可以连接,连好了之后就可以上网了。
》家用路由器构建出来的是局域网,所以,它只能用私有IP,私有IP构建局域网呢,给我分配的地址是192.168.1.201,另外一个家庭的家用路由器给他家的人分配的IP地址是192。168.1.201,所以,构建出来的IP地址可以是完全一样的,所以就有了这个子网和那个子网,虽然是不同的家庭,但是路由器虚拟出来的IP地址是完全一样的。因为这种IP不会出现在公网上,它是私有IP,所以,就相当于构建了一个局域网。曾经也讲过,在局域网当中的主机是可以直接通信的,换而言之呢,你家这台主机想要上网,这里就有一个概念了,你家里的面的路由器对外上网时,你家里路由器并不是直接通过它自己就到达公网上面了。你设备发消息给路由器,路由器不是直接到公网上帮你访问的,它做不到。而是你家里面的路由器,最后要把数据推送给运营商的路由器或者运营商构建好的在某一个市内或者省内所搭建好的路由集群,然后运营商再帮你数据转发,帮你把数据放到公网,在公网当中帮你去请求了对应的某些服务。
》换句话说呢,我们的家用路由器并不是直接访问公网的,而是得经过运营商,然后呢,才能访问公网。那么这里有一个问题,就是为什么我们家里面的路由器不能访问公网,而是访问的是运营商呢?因为你家里面的网,是运营商给你拉的,你顺着网线去找,就能找到运营商,就一定能找到对应的运营商的集群,换而言之,运营商帮我们把网线拉到我们家里面,同样的数据传送的时候,一定会走运营商,所以你的数据能够绕过运营商直接到公网呢?绝对不可能的!因为在物理上你不能的。有人是不是想过,我拿着手机绕过运营商,是不是可以直接访问全球公网,就不用话费了?当然不可以,因为网线就是运营商拉的,运营商又不傻,怎么可能把你的网线连的是公网呢?
》所以呢,从哪里可以看出来呢?给大家再说一下,一般家里的路由器是会有两套密码,第一套密码是你自己设置的WI-FI密码,也就是你在家里面设置好WI-FI密码,然后人家想连你WI-FI的话,给密码就行。还有一个就是,家用路由器内部,就是路由器里面也可以通过浏览器去访问,因为它有IP地址,是局域网的嘛,因为局域网当中的主机可以直接访问,所以你是可以直接访问路由器的IP地址,访问到之后呢,它是可以给你一个网页,能够配置路由器的,可以限制网速、连接个数。还有一个配置,就是路由器内部账号和密码,你的网是拿你爸的手机号弄的,账号是手机号,密码是自己设置的,往后呢,家里面网费没钱了,你爸拿着手机交了点网费,然后你的数据报在发出去的时候,运营商就识别到,当你想上网的时候,首先要对你做认证,认证你有没有交钱?你的家用路由器在访问运营商的时候,会先把自己的账号和密码信息推送给运营商,运营商就拿着这个账号和密码去认证你是否欠费,如果不欠费,就帮你转发了,如果你欠费,直接将你的数据报丢弃了。那么你就上不了网,你以为是你的路由器问题,其实是运营商截止了。就是如果你欠费了,你可以给运营商通信嘛?当然是可以的,这就是为什么你手机欠费了,上不了网,却依旧能打通10086的原因。
》此时呢,就又有一个问题了,就正如你所说,现在所有的上网呢,都是要经过运营商的,我是能懂了。但是我有一个问题,我的IP地址是192.168.1.201这个样子的,它要访问家用路由器,可是你曾今告诉过我,如果我封装的IP地址是192.168.1.201,我发出去之后呢,我想访问腾讯服务器,我的目的IP是17.77.241.3,我们构建的IP报文发送到运营商,然么腾讯服务器收到我的报文了,有一个问题就是,它要给我响应,响应的时候会填IP地址,难道它填的是我的私有IP嘛?曾经我们说过,公网IP是在公网上出现的,私有IP是不能在公网上出现的!如果请求的报文,封装的源IP地址是192.168.1.201的话,被发到公网上,那不就是私有IP地址出现在公网了嘛!因为我们每一个家用路由器都可以构建子网,大家构建出来的子网呢,子网IP可以一样嘛?很明显,可以是一样的。对于公网上的服务器呢,它要响应的时候,它到底是给谁响应呢?我们为了保证私有IP不出现在公网上,同时为了保证消息可以背推送回来,所以一般我们的路由器至少要有2个网口,一个是LAN口,一个是WAN口,其中家用路由器一方面连接的是家里面的私网,另一方面连接的是运营丧,而运营商内部呢,构建的,相当于也是一个私网,但是我们不讨论它的私网,其实一个道理。现在呢,我的数据报想转发出去的时候呢,是怎么转发出去的呢?首先我们出去的报文呢,源IP是201,目的是122,我们简写,此时填充的源是私有IP,目的是要访问的公网IP,然后呢,这个报文经过转发,到达了我们的家用路由器,家用路由器可以到达吗?可以,因为家用路由器的子网IP也叫做LAN口IP,是192.168.1.01,和我的192.168.1是和我的私有IP在同一个网段的,那么就在同一个局域网内,那么同一个局域网内的主机是可以通信的!所以数据报就转给了路由器了,路由器收到报文了,它知不知道,你是无法将你的私有IP推送到公网上的,说的不太严谨,主要是不主要没能说的很详细,但是原理可以说一下,后面在讲NAT的时候再详谈。路由器会自动做一件事情,它会把你家用路由器收到的LAN口IP,替换成WAN口IP,也就是路由器收到你的报文后,会将源IP改成了10.1.1.2。改完之后,家用路由器就替你把数据再进行转发,继续根据目的IP,发现你要去的目标IP肯定不是我运营商内部,所以转到运营商对外的路由器上,运营商自己内部也是一个私网,其中怎么办呢? 它也有自己的子网IP,即LAN口,也有WAN口IP,其中运营商的路由器的LAN口IP是10.1.1.1和你家用路由器的LAN口IP是同一个网段,即同一个局域网内的,所以可以两个路由器可以通信,那么就将报文继续转发给运营商的路由器,继续将源IP替换成自己的WAN口IP,也就替换成了122.77.241.4,替换之后呢,此时的源IP已经属于公网了,那么此时它替你去访问腾讯,然后腾讯推送数据报过去,怎么推送呢?填充目的IP就是运营商的IP122.77.241.4,至此我们就完成了前半部分理解,局域网/私网数据发送到公网是需要不断替换我们的源IP来完成的,这种技术呢,在不断推送过程中,不断在进行源IP地址替换,我们称之为NAT技术。
》我们想想,我们能够将数据送出去了,换而言之呢,我们有了这种源IP地址,路由器不断替换的做法,所以就可以不断构建大量的局域网呢,就可以照样让每一个局域网使用我们对应的公网资源了,而因为局域网当中的IP是可以大量重复的,所以就相当于隐形的增加了IP地址的数量。所以,我们刚刚讨论的是,数据报如何从内网到公网的过程。
在这里插入图片描述
》但是如何回来呢,我们放在后面说。总之,我们是可以有多个不同的局域网,它们使用的IP地址是可以完全一样的,因为该Ip地址只会在局域网当中被使用,而不会出现在公网上,当我们在访问外网时,我们可以通过不断源IP地址替换的方式,然后再进行我们所谓的交付到公网。所以,当我们在构建子网划分的时候呢,我么国家在搭设网络时,把公网IP划分到某个省,然后省搭设公网集群,所有省都自己的代表路由器,然后在省内部呢,比如说这个省由中国移动、联通、电信等负责,然后他们在省内部可以搭建各种局域网,所以私有IP就被分成了10开头、172、192开头的,如果是10开头的话,就可以构建大型局域网,那么就是运营商可以构建大的私网,那是不是就不需要再使用公网IP了,它后面就用私有IP做公网转发就行了。
》我们说过一个非常重要的话题,就是你的数据是可以经过运营商的, 这里给大家说一个题外话,如果我们想访问goole等呢?经常我们的请求被拦截了,现在告诉我在哪儿里拦截,谁拦截的吗?你想想你一旦欠费了,运营商能做到不让你上网,同样的你有非发请求了,它也可以通过一定方式甄别出来,不让你非法请求。
·一个路由器可以配置两个IP地址, 一个是WAN口IP, 一个是LAN口IP(子网IP).
·路由器LAN口连接的主机, 都从属于当前这个路由器的子网中.
·不同的路由器, 子网IP其实都是一样的(通常都是192.168.1.1). 子网内的主机IP地址不能重复. 但是子网之
间的IP地址就可以重复了.
·每一个家用路由器, 其实又作为运营商路由器的子网中的一个节点. 这样的运营商路由器可能会有很多级,
·最外层的运营商路由器, WAN口IP就是一个公网IP了.
·子网内的主机需要和外网进行通信时, 路由器将IP首部中的IP地址进行替换(替换成WAN口IP), 这样逐级
替换, 最终数据包中的IP地址成为一个公网IP. 这种技术称为NAT(Network Address Translation,网络地
址转换).
·如果希望我们自己实现的服务器程序, 能够在公网上被访问到, 就需要把程序部署在一台具有外网IP的服
务器上. 这样的服务器可以在阿里云/腾讯云上进行购买。

下面我们再谈一谈简单的话题,就是路由。路由话题呢,就不谈路由表生成了。路由表生成呢,可以固定配置,也可以自动的去进行识别,因为大家也知道,无论是在私网还是公网,给大家举一个例子,无论是在公网当中,省之间的一批路由器,还是在运营商内部的路由器,它们彼此之间,实现维护路由关系的时候,首先,无论是在公网当中的路由器,还是局域网当中的路由器,路由器都在它们的子网当中,所以他们之间是可以互相发消息的,所以他们互相发消息的时候,是可以得知每一个路由器上面的信息的,他们很容易建立所谓的路由表。
》所谓的路由过程呢,因为网络的结构,本质上是图形结构,结合我们前面所说的路由转发,其实我们在进行数据报从一个地方到另一个地方,在转发的时候,其实最终就是对应的一个,大家可以理解成是一个图论算法,这个是数据结构学的,我们不考虑。我们现在最主要的是要理解,路由是如何去查找的。
》首先当我们的报文在网络当中从A主机送到B主机的时候,数据报不是从A直接扔到B的,它跨网络传送的时候是需要经过一跳一跳的路由器的,根据我们刚刚所学,我们家里设备要先经过家里路由器转发到运营商,然后再转发到自己公网路由器的,比如说我要跨省,那么该报文即通过河北的路由器送到新疆,新疆再在自己内部做转发,反正数据报是一跳一跳的到目标主机的。这里就有一个最简单的问题是,当我们的一个数据报千里迢迢的送到目标主机所在的局域网呢,这里就有一个问题,因为IP地址 =目的网络+目标主机,所以报文在路上的时候,它是根据目的网络去进行我们对应的查找的。下面给大家举一个例子,另外给大家说一下,我们之前说过,一个报文在网络中转发的时候,目的IP是不变的,它要根据目的IP惊醒路径选择,就好比唐僧在路上,谁问他去哪儿,他都是说我要去西天。给大家举一个例子去帮助大家理解一下路由的过程。
》在坐同学都是懵懂经过高考的人,你考上了大学,比如说是在上海,那么假设你家是在贵州,你就千里迢迢坐着火车,你到了上海之后,你刚下火车,你正准备去同济大学的时候呢,你发现你的钱、手机都丢了,只剩下20元,你人生地不熟,不知道同济大学在什么位置,所以这个时候你该怎样去找到同济大学呢?最常见的就是,你又不知道,那你就只能问了。你逮住一个大爷问,我要去同济大学,我该怎么走?当你在路上问别人路怎么走的时候,你通常会得到几种答案呢?现实经验告诉我们,会得如下几种答案,第一种,我不知道,你别问我,我也是新人;第二种,有人不懂装懂;毫不疑问,我们的数据报面临的第一个路由器就是第一种情况,所以你数据报千里迢迢跑到某个子网问路由器,我要去120.11.91,1,这个路由器给数据报说,对不起,别问我,我不知道。这样是不是路由器有bug呀;如果大爷不懂装懂,他不知道也要帮你,那你目前有几种情况呢?第一种是,从前面左拐坐10号公交车,你下来之后再问其他人,因为这是朝着那个方向走的,然后你就听大爷的坐车出发了。下车之后遇到就是一样的情况,你继续问起他大爷了。第二种情况就是,大爷说,我也不知道,然后你看到那位大妈没,她是老市民,她很熟悉,然后你谢谢大爷,就跑去问那位大妈了,这叫做什么?这叫做,你查找路由表的时候,第一种情况是,路由表知道下一跳该怎么走,告诉你下一站应该到哪里;第二种情况就是,路由器并不知道你该怎么走,然后把你推送到那位大妈,这种情况就是,当路由器不知道你所去的地法是什么地法的时候,会把你推给默认路由。所以你就不断的碰到默认路由或者某些路由器知道,不断转发。这里要说一下,从概率上讲,你碰到的路由器,全都是第一种情况的,那么你就会无限趋近于你要去的目的地,因为一路都有人给你做正确指引,那有人说,一路上都碰到第二种大爷的答案呢?,会不会让我一直去默认路由呢?这种情况理论上是不会存在的,因为我们在不断被转发的时候,从概率上讲,我们一定会碰到有些路由器知道你该怎么走的,另外不要忽略路由器本身的主观能动性,当路由器收到了一个报文,当它不知道该报文怎么走的时候,这个路由器会直接和周围的路由器进行信息同步,总会有人知道,然后就要把消息更新出来,所以呢,当我们不断路由的时候,我们最终一定能够不断的逼近我们同济大学。还有没有第三种情况呢?有的!这个时候你又逮住了一个大爷,大爷就是同济大学的保安,至此你就到达了同济大学。在你下了火车站,到同济大学之间的这段时间呢,你在问路的时候,你永远问的都是,大爷同济大秀该怎么走,然后终于碰到同济大学门口的保安大爷,然后大爷告诉你已经到了同济大学,接下来你紧接着就是问大爷,同济大学18号宿舍楼该怎么走呢?其中,你刚刚在路上问同济大学怎么走,这叫做你在进行路由转发的时候,是根据目的网络来转发的,而真正的情况,你要去的是同济大学的18号宿舍楼签到。所以,你接下来问的就是,18号宿舍楼该怎么走?大爷是同济大学保安,那么他当然对同济大学的路况十分了解,他指明了去18号宿舍的路,这个时候,你就开开心心的完成了内网转发。
》所以,当我们进行路由的时候,我们先将数据路由,根据IP地址,因为IP地址被分成两部分,一部分是目标网络,一部分是目标主机。所以,当报文在路上传送的时候,是先要根据目的网络将你的数据送到目标网络,然后在目标网络内,根据目标主机进行内网转发,将数据转发到目标主机上,这就是路由的过程。
》路由的过程, 就是这样一跳一跳(Hop by Hop) “问路” 的过程. 所谓 “一跳” 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。
》IP数据包的传输过程也和问路一样.
·当IP数据包, 到达路由器时, 路由器会先查看目的IP;怎么查看呢?你的IP是有自己的IP地址,你的路由器内部是配置了对应的子网掩码的,所以,我们的路由器是拿着你的IP报文,从报文里面提取出目的IP,拿目的IP和自身的子网掩码做按位与&,然后再拿着目标网络在自己的路由表当中进行查找,路由器会决定将目标直接转发给下一跳,或者是我们对应的默认路由或者直接转发给目标主机,依次反复这样就能够根据目的IP到达目的IP所标定的目的网络,到达目的网络之后,就能找到目标主机。
·路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;
·依次反复, 一直到达目标IP地址;
》如上就是我们对应的IP,对我们来讲,IP协议呢,重点是理解两大大块头,第一个就是IP报头,第二个就是理解网段划分,重点不在于理解子网掩码,你得整体构建出来网络的宏观图。

现在呢,我们能够理解一个问题了,什么问题呢?就是数据可以通过主机B,通过IP,再查找路由表,然后根据我们的子网划分构建好的网络,然后根据路由器当中的子网掩码和我们的目的IP进行按位与&就能够得到目的网络,再进行逐步转发,最终将数据报转发给目标主机。
》可是IP毕竟解决的是提供一种能力,将数据从主机A转发到主机C的能力,但是你并不能100%做到呀,在某一个路由器上,数据报出现排队了,这个路由器忙不过来了, 或者路由器干脆将你的报文丢弃了,或者你数据报的TTL生存时间到了,或者在不断转发的过程,数据的bit位出现翻转等等,反正就是你丢包了,怎么办呢?我们有上层协议TCP帮我们进行重传,因为上层协议没有收到你的重传的时候,会通过滑动窗口将你发送的数据暂存起来,直到收到ACK的时候,滑动窗口才会移。所以收不到就会超时重传,重新构建报文再进行转发,可是你再怎么牛,你把数据从主机A送到主机C,你不是直接送过去的,你还得一跳一跳的送过去。你刚刚讲的IP,我们的路由器F为什么要到路由器G,回答到是这个问题,查路由表你告诉我的是,是通过eth0(发送端口)扔出去,可是我知道我的数据报要转到下一跳路由器,或者我路由器要交付给主机,我要解决将数据从主机A送到主机C的问题,我是不是得先解决将数据从主机A转发到,下一跳路由器F到问题,从路由器F再到路由器G到问题,一定要记住一句话,数据报一定会一跳一跳的转发,而我们从一个主机到另一个主机(路由器也算主机)有一个前提条件就是,相邻的两个主机一定在同一个局域网 。主机A将数据转发到主机F,一定是主机A荷主机F在同一个网段,同一个局域网内的主机才能够通信,而主机F要把数据交给路由器G,一定是F和G在同一个局域网内,所以,我们将数据从主机A到主机C,本质上是,把我们的数据不断的在一个个子网当中进行转发,因为局域网可以直接通信,所以我主机A能跟F通,主机F能够跟主机G通,就意味着主机A可以和主机G通信,以此类推。所以,我们的数据为什么能够最终到达主机C呢,取决于能够一跳一跳的到下一个主机,本质是从一个子网跳到下一个子网,这个子网可能是运营商内部的子网,可能是公网维护的一大批路由器或者交换机,所以无论是内网转发,还是公网转发,说白了都是子网,所以所有的数据报都是在子网当中进行转发的。所以,我们全球的网络本质上就是通过一个个局域网构建的,所以我们后面要解决下一个问题就是主机A要到主机C就要解决先到路由器F,如何在同一个局域网内,将主机A的数据交给路由器F呢,这就是数据链路层要解决的问题。 如果数据链路层将主机A到主机F的问题解决了,那么主机F和主机G在同一个局域网吗?在呀,在的话不就直接将数据交付呗。所以接下来我们要解决的就是局域网转发的问题。下面我们重点要谈报头问题,以报头为切入点,详细的局域网当中的数据报如何转发,只要局域网结局了,那么主机A到主机C就解决了,那么上层丢包也就能解决了,那么TCP可靠 通信就能解决,也就是数据能从我们的A到C就能解决,那么上层应用就能拿到数据,进而你才能够进行套接字编程,进行序列化和反序列化,进行数据相关的处理,所以我后面说。

数据链路层

我们再进一步,照样你上面讲的一些东西我还是不清楚,诸如,你说我们的IP要进行分片,好的,分片我是知道了,但是我就是不理解,分片的数据大小是多少,这是第一;第二,为什么非得设计分片的标准;
》包括你说我们的IP能够将数据从主机A到主机B(不保证可靠性)IP的本质核心工作是将数据从A主机送到B主机,它提供的是一种将数据跨网络传输的能力,但并不代表他一定能做到这件事情,所以就要有上层的TCP来保证这个能力。可是呢,你想想,将数据报从A主机跨网络送到B主机,那么前提条件你是被得将数据从A主机送到B主机。
》同时你也讲了,我们对于IP的理解呢,它本质上是一个一个的子网,通过把我们一个一个的子网用路由器连接起来就可以,所以,在内网当中,我们在进行转发的时候,首先要考虑的是数据怎么从A主机送到路由器出口或者路由器的入口当中,这个工作怎么做的呢?所以属于数据链路层要解决的事情。
》我们的问题第一个就是,MTU(最大传送单元)问题,也就是数据报划分问题,你曾经说,我们曾经讲的内容在IP那里是要进行分片的。曾经你也讲了,为了减少分片又应该让谁去做呢?为了减少分片我IP该怎么做或者上层协议该怎么做?第二个呢,我们要谈一谈,我们IP 和 MAC帧的正儿八经的区别了。
》下面我们先画一张图,按照你所讲的,你是这么说的,我们有很多的子网,这些子网用对应的路由器来进行连接,在子网当中会有很多的主机,假如现在有一台主机A要把数据交给主机B,现在的问题是,你要将数据从主机A交给主机B的时候,我们之前讲过,我们是不是要通过各种路由选择,然后才能将数据交给B对不对。可是呢,你说过IP地址的核心工作是一种能力,将数据从A主机经过路径选择交给B主机,交给B主机,经过路径选择呢,我们一定是有一个目的IP不断的进行查路由表。比如说,A主机本身工作在传输层的主机,它有网络层,当出来一个IP地址,比如说目的为IPB,它转发的时候,首先查自己的路由表,发现要转发的目的IP和自己的子网掩码按位与&不是自己的局域网,就将其扔到了出口路由器,然后路由器进一步的将我们数据再进行转发,再进行转发就有可能到达我们主机B了。
》最简单的,我们的路由器收到一个IP报文,它呢也是根据你报文里面的目的IP,然后和自己的子网掩码按位与&,首先确认这个报文不是发给自己的,然后也不是发给自己这个局域网的,怎么办呢?直接把它扔给其他路由器了,有可能有其他路由器和它关联着,和它关联着呢,它在查的时候就要看到目的IP和子网掩码按位与&后,看是和哪个路由器会有关联。举一个最简单的例子,我们在进行我们对应的路由的时候,这个目的IP本身是被划分过的,然后我们就看一下去的目的网络,是能够更快的定位我们的目的网络,还是去的目标路由器它所对应的这个,我们可以称之为,集连的目标网络呢,和我IP里面的网络号根本就不匹配,如果匹配的话,我就直接将数据报转给该路由器了,不能匹配就转给另一个路由器,当然还会有默认路由。相当于我们的路由器呢,和周围的几个路由器是在同一个局域网的,所以几个路由器之间是可以互通有无,将对应的相关网络信息全部都让彼此知道,那么路由器之间可以知道互相集连的目标网络是谁,那么路由器就可以根据我们IP数据包的目的IP中的目标网络来进行下一跳的转发,也就是供路由器来进行决策。如果你不太理解也没关系,最简单的方式就是,现在对我来讲呢,我数据报在进行转发的时候,发现目的IP和路由器的子网掩码进行按位与&发现,确实连的不是该路由器的局域网,然后就再进行转发给其他路由器,最后一路过去就到达了主机B。
》那么这里就有一个问题,我们一直说,IP地址解决的是从A主机送到B主机的能力。可是呢,你要将A主机送到B主机这样的能力呢,你是不要首先解决第一个问题,你决定要把数据从A主机送到路由器了,那你是不是得先把数据送到路由器上,那你决定送到另一个路由器,你得再决定怎么把数据交给那个路由器,以此类推方法下去。所以,我们这里又有一个字问题就出来了, 我们IP:**提供一种能力,将我们的数据报从A主机跨网络送到B主机的能力。**但是A和B根本不在同一个网段,你首先要解决的是,将数据从A主机送到下一跳的能力!
在这里插入图片描述

》这个道理就跟,假如你家里有年纪很大的老人,腿脚不便,你和姥姥说,我们去云南玩吧,这时候你爸就会骂你,你姥姥走出村口都不便,怎么出远门玩。所以,你把数据从A主机送到B主机,前提条件是,先把数据送到下一跳,如果你连下一跳的能力都到不了的话,那就别谈什么数据转发了,这点要注意。我们又说了第二点,当我们进行数据报转发的时候,其实就是把数据从一个子网送到另一个子网的过程。我们从一个子网送到另一个子网,那么我们先,因为一个路由器是横跨两个子网的,所以换句话说,我们只要把数据报转发我这个子网的路由器,这个路由器集连下一个子网的话,我们把这种在局域网内转发的行为呢,也可以称之为跨网络转发。相当于只要把数据交给了路由器,它横跨两个子网,只要交给了它,首先在交付上是一个内容转发的行为,但是在逻辑上呢,就相当于你把数据报从这一个子网转发到下一个子网。所以,我们要解决从A主机跨网络送到B主机,你得先解决下一个问题,就是将数据从A送到和它同一个网段的另一个主机(路由器)这样的能力,这就叫做局域网转发。
》那么其中呢,我们可以想象一下,我们以前讲的网络协议栈,我们能够明显感觉到的一个点就是,其中,我们把一个数据在局域网内部转发,这个其实就是下两层决定的(链路层、物理层),更重要的是,转发策略一般都是由我们对应的数据链路层决定的,我们可以想象一下,假设我们已经知道了数据链路层负责的是将数据从A主机送到B主机,其中这个数据链路层,物理层我们先不考虑,数据链路层呢,他可以把数据从一个子网把数据从A主机送到B主机,在内网当中进行转发,既然它能在内网当中把数据报送到任意一台主机,那么他也一定能将数据送到内网当中的任意一台路由器,只要这个路由器横跨两个网段,那么把数据交给路由器的过程,就意味着将数据交给了另外一个网段,这就实现了跨网络传输的过程。还有一个呢,当我们数据报在进行转发的时候,你为什么把你的数据报交给路由器而不是交给局域网的另外一台主机呢?交到下一个路由器后,路由器为什么不交给它网段内的主机而是交给另外一个路由器呢?原因是我们的目的IP提供了目标网络和目标主机,我们需要目标和目标主机来进行路径的路由,所以,我们在路径选择的时候,选择了应该到下一个路由器,所以,网络层给我们提供了找路的能力,数据链路层呢,我们称作,在内网当中,从一点到另一点的能力,而网络层给我们提供了寻找路径的能力,如果我们网络层和数据链路层合起来呢,既能找路又能走,那么我们就提供了把数据从A主机经过路径选择跨网络送到B主机的能力,这两层提供出来了。在转发的时候,有可能被路上的某些路由器丢包了,或者出问题了,或者网络出现拥塞了,怎么办呢?没关系,我们还有上层传输层帮我们提供可靠性。所以,一旦我们底层转发出问题,我们传输层会继续让底层重发,所以这就是为什么传输层经过滑动窗口,它里面会暂存你已经发送的数据,当我们没有收到应答ACK的时候,会让我们的底层再次将数据重发。所以传输层、网络层、数据链路层这几次已经能够提供将数据从A主机可靠的送到B主机,经过路径选择,可靠地送到B主机到能力。只要能A到B,那么一定B能到A,所以呢,我们传输、网络、链路呢,核心解决的是数据报可靠传送的问题。
》我们之前也说,你把数据可靠地送到B就完了吗?还没有,你还得让应用层来进行我们数据解析,来供上层某种业务处理,比如说我们网络版本计算器,读到某些数据时,我们应用层要根据报头读到有效载荷,这是第一步;第二呢,我们读到有效报文,我们要对报文做反序列化,将我们序列化后的字符串,格式化成我们面向对象式的结构化数据,然后上层是不是就可以用语言来处理它了,这就是网络划分的时候,每一层的核心制造。

下面呢,我们有一个问题,你怎么做到,将数据在内网当中实现转发的呢?我们来看看我们下一个协议,以太网帧格式协议。
》关于局域网的协议呢,我们之前在讲网络基础一的时候,早就提过一次,不过待会儿我们还要再说。下面呢给大家讲讲以太网或者令牌环网是我们在局域网当中所采用的标准。以前在学IP和MAC地址的时候,或者说学IP和TCP的时候,从来没有讲过windows和Linux有什么差异,我们也从来没有谈过网络当中的差异,我们一直都在谈到是,TCP是什么、IP是什么,都是在说这样的话题,可是呢,为什么一到了链路层就要告诉大家,这个网络的差异呢?因为,事实上我们一定要记住,在最开始的时候,网络并没有被广泛所使用的时候呢,我们有各种各样的实验室有主机和主机之间通信的需求。
》下面我要说的是,全球这么大,底层网络,就局域网中转发这件事情上, 底层通信的方式呢,是有差异的。所以,我们重点讲的是以太网格式,这是其一 ;其二呢,底层网络虽然有差异,但并不影响我们网络在全球铺开,原因就是因为有IP地址的存在。因为有IP和路由器的存在呢,我们在进行路由转发的时候呢,比如说,MAC帧,但是一旦我们在路径选择的时候,我们用的是IP地址。所以,IP是全球唯一的,就不会出现全球网络因为底层差异的问题而导致不能联通的问题。稍后我们还会再说。
》下面我们谈谈局域网,局域网常见的就是以太网格式。
在这里插入图片描述
》“数据”字段,就是上层交给我的有效载荷,上层指的是谁呢?通常指的是IP协议,也就是整个IP报文交给了我们的MAC帧。当然我们一会儿还要去讲ARP协议,也有可能是ARP报文。
》再下来就是“目的地址、源地址”字段,和IP没关系,这里指的是目的MAC地址和源MAC地址。这个MAC地址通常代表的是48位,在网卡当中植入,具有唯一标识的地址,我们称之为MAC地址。那么其中,目的地址和源地址,虽然我们经常听到有人说,MAC地址是全球唯一的,不要受它全球唯一性的影响,可能是教材想要通过全球唯一性来更加帮助你强调MAC地址的唯一性,但是往往很具有误导性。这个目的MAC地址和源MAC地址,代表的是48位的MAC地址,它虽然是全球唯一,但是我们更重要的是,我们要求它在局域网内部唯一就可以。也就是,你在一个局域网内,保证MAC地址唯一性,我就谢天谢地了,当然能够做到的哈。所以,MAC地址一共有6字节,48位,有目的MAC地址和源MAC地址。其中呢,我们局域网每一台主机在自己的数据链路层当中呢,都要有自己的身份标识,就是通过MAC地址,也就是每一个主机都有自己的唯一标识。
》下面问大家一个问题,同样的,我们今天要学习的是以太网帧格式,我们面临的问题是,第一,请问报头和有效载荷如何进行有效分离?第二,我们为了一个收到MAC帧的主机,它应该如何向上进行交付。这两个问题是我们在学习http和https,以及在我们学习所对应的TCP、IP,每一个协议,都是必文的两个问题,首先得想明白,是如何进行解包的和分包的;然后再理解,它是如何分用的。这样的话,你脑海中的数据报转发的逻辑才不会断。
》我们能不能将我们的以太网数据帧分包和解包呢?只要能解开,曾经的分包方案一定也是可以的。怎么做呢?它的以太网帧格式呢,“目的地址”、“源地址”、“类型”都是固定大小的,还有一个“CRC”字段也是固定大小的,所以6 、6、 2、 4字节大小,简称666,其中对应的就是以太网帧格式,它附加的相关的报头或者说是校验字段。所以对我们来讲呢,我们有6位的目的地址,6位的源地址,2位的类型,4位的CRC,我们只要差异性记住,对应的类型和CRC,它的报头部分呢其实就三个,目的、源,还有一个字段是在结尾CRC,主要是用来做校验的就可以了。因为是固定的666,所以我们在对以太网帧格式在做提取的时候,我们可以6 6 2提取前三个报头,然后将最后的4个字节扔掉,剩下的就是有效载荷,所以,很显然是能够拆开的。能拆开,那么就一定能够封装,这是第一个。那么第二个,它又是如何解决,交付的问题呢?以太网数据帧呢,它脑袋顶上有很多的协议,至少目前我们知道是有IP协议,未来呢,还有ARP、IRP等。可是它的脑袋上有IP的时候,它怎么知道要把数据交给IP呢?那么其中就有一个2字节的“类型”字段。这个类型字段,我们称之为帧类型,通常代表的就是有效载荷应该向上交付给哪一层协议,所以帧类型如果是0800,对应的有效载荷就是IP数据报,当然还有0806、0835对应的就是其他类型数据报。那么其中呢,我们就可以证明有效载荷时属于什么类型,就可以进一步向上交付就可以了。所以以太网帧格式就这么简单,就只有目的、源、CRC、类型。所以,我们就能够做到封包与解包和分用的问题。

我们半新内容,半复习的帮大家来谈谈第二个话题,就是局域网的通信原理,其实早就说过了,我们就要正式引入MAC地址了。局域网内有很多的主机,主机分很多种设备类型的哈,每台主机都接到了对应的网络,那么将它们整个组合起来的网络叫做子网,或叫做局域网。当我说这句话的时候,就要意识到,我们只要将一个局域网搞定了,那么路上路由碰到的其他局域网也就搞清楚了。
》局域网和局域网之间是如何串起来的呢,是由子网划分决定的,是运营商投入基础设施决定的。根据你前面说的,每一台主机都必须得有自己的MAC地址,每一台主机都可以接入到局域网。局域网当中,主机之间是可以互相通信的,其实可以想象成,每一台主机都接入到同一根线上的样子哈,因为能够互相通信,所以这根线肯定要被大家看到。
》再说一下,我们首先要理解,每一台主机都共享同一个网络,网络太抽象了,我们就将其想象成都连在同一根线上,所以,所有的主机都得通过连同一个网线,才能实现主机之间相互通信呀。MAC1是一个独立主机,MAC6也是一个独立主机,他们两个具有独立性,它们想要通信,那么必须得先让他们看到同一个根网线。能够想到什么呢?再说一遍,M1是一台独立的主机,能够进行数据的发送和接收,将数据转给M6,它两主机是独立的,要想通信,就必须得先看到同一个网络/网线。这个不就是,两个不同的进程具有独立性,要想它们通信,就必须得让他们两个看到同一份资源。你的主机和他的主机是不是同样的主机呀,要想让他们通信,是不是就得看到同一份资源呢?在物理上也要遵守这样的设计哲学。
在这里插入图片描述
》你们两台主机具有独立性,你们两个必须得看到同一个子网,虽然网络我们想象不出来,我们就将其看成一根网线,必须得这么干,要不然怎么保证你们两实现通信呢?你们两个连介质都没有,怎么通信呢?我们在通信的过程呢,我们其实之前是这么讲过,这个通信过程有点像什么呢?就像我们在班级里面上课,我们之间在正常通信,假设我们一间教室里面,我说张三,你作业为什么没做,我们班级里面的同学听到这句话呢,大部分同学根本就不会站起来,有的甚至连反应都没有,只有张三同学才会颤颤巍巍站起来说,我早就做了,你没看。我就说,那行,我下去看看。我和张三聊的火热的时候,我们周围是有一大批的吃瓜群众的,我们就要想想,当我和张三进行沟通的时候,我们在坐的其他同学,听到我和张三沟通了吗?答案是;你们听到了。但是你们为什么不做反应呢?因为你听到这句话的前提是你收到了这句话,你对这句话做分析的时候,你发现这个老师叫的学生的名字是张三,你是知道自己的名字的,所以你呢,就拿老师喊的名字张三和自己的名字做对比,发现不是叫自己,所以你就在自己的大脑里面,自动将这条消息丢弃了。所以,你听到句话的时候,你不做反应,只有张三会站起来颤颤巍巍说,我作业做了。当张三跟我说的时候,你们听到了吗?你们全部都听到了,你们并不会对其做处理,因为你们收到消息,对其进行分析,提取有效载荷,发现不是叫你,那你就直接将其丢弃掉了, 只有我收到了这条消息,此时就可以进行对应的数据处理了。当我和张三在教室进行通信的时候呢,我和他认为,我在和张三沟通,认为,因为在这种环境当中,是认为彼此在进行沟通,这也是我们之前举的例子,结论就是:**我们局域网通信看起来是两台主机在进行局域网直接通信,但是周围有一大批的吃瓜群众都能听到。**这个问题,我们在讲网络基础一的时候就讲过了。
》下面要说的就是,能不能结合具体报头来和大家谈一谈呢?所以,我们将以太网帧格式的报头拎出来和大家看一看,我们该如何理解他。我们在这里就将目的、源地址字段给抹掉了, 类型字段呢,假设双方主机是用IP协议进行通信,接下来我们就要来填一下字段。
》假设,我就要M1和M6来进行通信,此时怎么办呢?我们的主机M1要发出去一个报文,第一个字段是不是目的地址,那么M1要和M6通信,目的地址是不是就要填M6的MAC地址呀,那么M1在进行数据报转发的时候,发现他要把数据转发给M6,那么就有一个小问题,M1怎么知道要把数据交给M6呢?谁决定的?假设M6是路由器,M1怎么决定将数据交给M6的?是不是根据我们的报文所要去的目的IP地址决定的呢?它是根据IP地址决定它要去M6的,能理解吗?因为它在进行判断的时候,发现目的IP地址是跟我在同一个网段,也就是在同一个局域网的,所以他应该去M6,这里也有一个潜在问题,稍后再说。
》第二个就是,我们这里有一个源地址,我们应该填谁呢?是不是就填的M1呀,我们在继续。假设,我们双方是IP层在进行通信,IP呢是类型是0800,所以类型字段就填上0800,数据当然就是从上层交付下来的。所以M1就拿着数据报经过路由转发,发现就是要给M6的,怎么办呢?它其实不知道M6在哪儿,所以它把我们的数据报呢直接扔到了网络当中。下一个问题,当数据报被扔在局域网当中呢,我们的m2、m3、m4等等主机能不能收到这个报文呢?要不要收这个报文呢?要呢,就是这些主机要将数据报收下,它要把自己的数据拿到自己的协议栈当中,至于你后面怎么处理,那是你后面的事。答案是:**每一台主机必须要收的!**也就是,凡是在网络当中的所有的主机呢,它无时无刻都要从我们的局域网当中抓取数据,只要是局域网有数据了,所有的主机就必须将数据报拿到自己的主机里面,因为只有拿到,才能确认是不是发给自己的。不管是发给自己的,还是判断出不是发给自己的,对于我主机来讲,都是有意义的。所以,记住了,在局域网当中,你的电脑,你的笔记本哪怕什么都没干,你的笔记本也无时无刻的帮你在局域网当中收取数据,因为你要随时随地要在局域网当中拿去数据!
》也就是说呢,我们对于机器的理解,不要那么死板,不要认为你的机器放在那里不做事,实际上呢,你的机器无时无刻的都在想办法从我们局域网当中获取数据。就算M1自己发出去的数据,他自己都得再看一下。只不过呢,大家获取的时候,第二个问题,**每一台的主机哪一层协议先获取到数据帧呢?**毫无疑问应该是物理层先获得,不过我们先不考虑物理层,每一台主机都要获取呢,肯定物理层要解决,它肯定要先拿到,但它是硬件哈,我们就不管。一定是谁呢?一定是主机的数据链路层!换句话说呢,我们记住了,网络始终都是终于链路层,始于链路层的。也就是,当你的数据报发送的时候,最后一层协议是终于链路层的,当我们每一个主机收到数据的时候,都要始于链路层,因为你要自底向上交付,所以每一台主机收到数据的时候都是要从链路层先收到。
》每一层收到的时候,而正好你发过来的数据帧,最外层协议的目的、源、类型、CRC正好都是我们数据链路层对应的报头,每一层协议都在最底层先收到数据帧,然后做什么工作呢?每一个主机数据链路层协议的解析(解包+分用)。所以,每一台主机收到报文都要做一件事情,将报头和有效载荷进行分离,能分离吗?能的,我们前面说了,字段都是固定大小的。将报头和我们对应的有效载荷我们在进行分离之后呢,那么接下来我们要做的就叫做从报头当中提取有效载字段。其中呢,我们发现它的目的MAC地址填的是M6,然后就是对比目的MAC地址和自己的MAC地址是否相同。我现在作为主机M9,我收到数据帧,将报头和有效载荷进行解析,解析之后呢,发现你填充的目的地址M6和我自己相等吗?不相等时,此时我就有两结论了,一旦把这个工作懂了,那么我们数据报转发就有完整的思路了。如果不相等,我们可以做什么呢?进行丢弃。不相等就丢弃意味着,我们没有收到这个数据。一旦最底层数据报被链路层丢弃了,上层能知道有这个数据报的存在吗?上层是不知道的。如果是相等的,那么我们向上交付(分用),然后就继续看我所对应的类型字段,来将我的有效载荷交付给上层的谁,那么进而可以进行下一步协议栈的处理了。
》所以,当我M1发了一个报文给M6,最后局域网当中的所有主机都收到,只不过大部分的主机都将其丢弃了。那么丢弃之后怎么办呢?那么是不是只有M6主机会处理它呀,这就是局域网的通信原理。
》所以,我们再来看一看我们的数据报转发的时候从A主机送到B主机,现在我们就有一个真实的能力了,以前的能力都比较虚。A主机经过路径选择将数据送到B主机,现在我们知道了,你得将数据送到同一个局域网内的某一个主机,所以我们的A主机能不能够将数据送到局域网内的任何一台主机呢?能,一定能,因为局域网内的所有主机都可以相互通信,既然能送到任何一台主机,那么路由器肯定也能送。所以能将数据经过路径选择跨网络将数据送到另一个网络,那么我们的IP就能够帮我们进行路径选择,将数据送到B主机。同样的,丢包的话,我们上层还有协议,所以,一切的一切到这里我们就有答案了。这时其一。
》其二呢,按照你的说法,我们在局域网当中呢,我们的所有主机其实是收到这个数据,只不过是把数据扔掉了对不对?对的。那么有没有可能我在局域网当中把别人发来的数据不丢弃呢?是可以的。网卡有一种模式就是混杂模式,一旦设置好后就不做数据甄别,那么就将局域网当中读取到的数据一股脑塞给你,那么你就可以将数据拿上去使用。所以,这也就是抓包,你想抓包,前提是你得收到包,一般抓包软件都会自动设置网卡的混杂模式。
》再下一个,按照你的说法呢,我们今天的M1、M2、M3等等主机呢,这么多台主机,我们的局域网都是共享的,你M1相往网络里面发数据,有没有可能,M5这台主机也想发呢?我们的主机可是独立的,你M1发你的,我M5发我的,我们不冲突呀,你发你的,我发我的,此时冲突吗?答案是:冲突的!因为M1和M5发出的数据呢都是在网络当中走的光电信号,如果两台主机同时发送的时候,光电信号说白了就是波嘛,也就是有频率嘛,它们之间是会相互干扰的,一旦干扰的话,谁的数据都别想发出去,这个情况呢,M1发数据时,M5也想发数据,进而导致数据干扰的问题呢,也叫做数据碰撞。数据碰撞之后呢,其中数据相互干扰,那么大家都过不好。此时我们就需要M1和M5两台主机,随机的等上一段时间,再进行在局域网当中作数据转发。所以,我们通过在时间层面上,把M1和M5的时间岔开,让他们岔开之后进行发送,然后就不会互相干扰了。
》这里太多好的东西了,第一,我们将整个局域网当中呢,M1和M5能够相碰,和其他主机是不是都有可能相碰,所以我们把这么一个局域网呢,也称作碰撞域。大家也别怕,碰了也不怕,内部是有策略,一会儿再来谈一谈,把概念先跑出来。我们先和我们以前的只是挂靠一下,M1发了消息,M6也在发消息,它们就有可能互相干扰对不对。那么问大家一个问题,首先M1和M6是互相独立的主机,他们要通信就必须有网线资源,所以M1和M6进行数据发送时,就会出现数据碰撞问题。他们两个呢,是先进行发送,看看有没有碰撞,如果碰撞了,那么我们就碰撞避免,我们每一个人就休眠一段时间,过一会儿再发,这样大家时间差不同,就有可能在概率上岔开碰撞的时间了。那么我想问一下大家,首先这个网络资源呢,只有一个资源,因为是公共资源,所以你做的事情,说白了就是,碰撞就不要了,每碰撞才能发,换句话说,这个公共资源在任意时刻只允许有一个主机向我们对应的局域网当中发送数据,是的!然后其中,M1和M6在进行发数据的时候,碰撞了就不要了,任意时刻我们可以理解成,我们期望要的是,理想情况是,最终只有一个主机会向网络当中放数据,所以这个网络资源,我们可以用一个全新的,或者老的视角,或者在网络上是全新的视角。我们把网络呢,想成一根网线,相当于是临界资源,其中M1和M6呢,想象成两进程,所以,我们对应的网络资源就称作M1主机和M6主机的公共资源,然后我们是有碰撞问题,不能让他们发送,,如果同时发了就会造成数据不安全,数据不一致的问题,所以我们要解决这个问题,我们就要通过一定的方式来保证公共资源的安全,让公共资源变成临界资源,此时我们就可以采用M1和M6基于碰撞的方式,来保证我们的临界资源在同一时刻只允许一个进程在使用。所以,从系统的思想呢,照样可以解决网络当中的问题。
》所以对我们来讲,M1、M3、M6等主机,组成的局域网资源呢,就是一个临界资源。所以,你经常有了对应的碰撞检测的各种算法,你为什么要碰撞检测呢,你就是想让这个局域网具有唯一性,在任何时刻都只允许被一个人访问,这不就是临界资源的概念吗?只不过,我们以前在系统层面上我们是经过加锁,你是先申请锁再访问,现在M1和M6是先发数据,如果有问题了我们再说,所以处理方法不一样罢了,这是从系统视角。
》现在,我们回归到网络视角,我们把整个网络呢,称之为一个碰撞域。下面问大家一个小问题,你说在一个
局域网当中,主机越多越好,还是主机越少越好呢?
不用想呀,越少越好,因为发生碰撞的概率就越低。可是,我们局域网当中的主机就是非常多,那怎么办呢?所以,一般我们局域网主机太多了,大家在小教室上课和大教室上课,体验完全不一样,主机越多,发生碰撞的概率就越大,直接后果就是,大家在局域网当中无法进行正常通信,很容易出现碰撞,会很卡。这就是为什么一旦你逃课在宿舍玩的时候,网速很快,一栋楼基本上没什么人,但是一到网上,就会觉得很卡,这就是因为局域网当中的主机变多了,碰撞概率增加了,其实不是网卡,网卡本质是丢包率变高。
在这里插入图片描述
》可是我局域网当中的主机就是有很多,怎么办呢?所以,我们为了尽量减少我们在局域网当中发生碰撞的概率,在硬件上呢,我们有一个基本的交换机或网桥设备。我们的交换机或者网桥它们主要做的是,比如说,我想让某几台主机处于局域网当中的某一个子区域,我们在局域网当中就有了一个设备,这个设备呢,可以把大的局域网划分成好几个区域,我们的网桥有一个作用呢就是,凡是在某一个区域内的主机发送数据的时候,比如说M1想给M3,就直接发送过去,那么数据报呢,就没必要往其他地方走了,那我就不往其他地方扩散了,那么变相的就是其他地方的数据就相对比较少了,这是其一;其二就是,一旦我们的M1想给M2发消息,M2想给M3发消息,两个数据发生碰撞了,网桥或交换机这个设备呢,它们不会让已经碰撞的一些数据报呢扩散到其他网段。也就是在每一个网段内呢,你们自己内部能够解决就内部解决,就不要扩散出去,如果碰撞了,我也不会转发碰撞后的报文来影响别人。如果M1想给M4发消息呢,我就正常的局域网通信,我照样的M1在局域网可以转给M4,如果在转发的过程当中,如果发生碰撞了,我们也不发生扩散。换句话说,因为有交换机这样的设备存在呢,它将我们对应的一个大的子网划分成一个个小的区域,这个小的区域当中呢,合法的请求给你转发,非法请求,或者你们在你们的一个小区域内可以完成的,就不要向外扩散了,进而尽量可以减少我们碰撞域的体积,我们称之为,交换机的核心工作,除了在局域网当中进行数据帧转发,不转我也是可以发送的,但是核心工作是划分碰撞域。也就是将碰撞域划分成一个个的小区域。虽然局域网无法避免一个大的局域网内进行碰撞,但是可以在一定程度上减缓我们主机之间碰撞的可能性,这就是我们称之为交换机的作用。
》有人说,我怎么保证,你M1、M6它们之间经常聊天,那我将他们划分到不同的区域合理吗?答案是,当然不合理呀,当我告诉你有一个设备被引入的时候呢,曾经有无数聪明的大脑,早已经决定过了,是该如何把这个设备在我们局域网当中如何进行划分的,如果你两台主机通信的情况特别频繁,我就可以把你的M1和M4划分到同一个碰撞域里面,然后你们去聊,你们不要影响其他人,这个是经过设计的,这是在硬件上根据我们局域网通信的原理,在硬件上我们有的策略,然后在软件上呢?
》你说在我们这一个大的这么多的主机当中,如果M1是个话唠,它不仅仅是体现在话多,还体现在话长。我请问,如果我们在一间教室里面沟通的时候,是很短的一部分数据,相比较于,每一个人都朗诵一篇800字的文章,是在什么情况下,我们发送的更长更容易碰撞呢,还是更短更容易碰撞?因为局域网是具有一个光电信号的特性的数据,如果在硬件上,我们每次单次发送的数据量更长,更容易发生碰撞呢?还是更短,更容易发生碰撞呢?答案是:一定是更长更容易发生碰撞。如果你M1发送的一个数据帧更长,也就意味着,M1把自己的数据发送到网络的时候,会花更多的时间,也就是说,M1在更多的时间范围之内呢,M3和M4在这个时间段内,就有可能和M1发生碰撞了。就比如,我们打战的时候,我们陆军世界第一,我们最擅长的就是游击以及战后穿插,我们是带着大部队在敌后穿插不容易和敌人碰在一起呢,还是带着小队伍不容易和敌人碰在一起呢?答案是:一定是小队伍,队伍越小,和敌人碰撞的概率就越低。你数据量很大的时候,你就要不断的要向网络里面发送数据,别人发送的时候,就会和你发生碰撞。
》严格意义上讲,在软硬件结合上,一般MAC帧一般体积不要过大,会大大增加碰撞的概率。一旦碰撞了,其实就是否定之前做的工作,一旦出现体积太大了的话, 在网络当中很容易出现碰撞的话,其中呢,我们网卡花费很大时间才将数据发到80%,好不容易到100%就不行了,所以,我们就化整为0,将我们的数据拆成不要太大,就可以在网络当中快速的将数据转发出去,虽然碰撞了会有损失,但是损失不会太大。以前你要发数据是1M,哪怕碰了1bit位,那么前面的数据就没了, 如果你划分成一个个小的数据,那么成本会非常低,即便碰撞了,把这么一个小的数据重发一遍就行了,所以对我们来讲呢,我们的MAC帧的体积就不要太大。
》MAC帧太大由谁决定呢?MAC帧说我就是一个跑腿的,就一个办事的,别人把数据给我,我添加上我的报头让后向下发送,我说了不算呀,网卡对MAC帧说,你说了算,你是硬件,所有人都要通过你发送,MAC帧数据的体积不要过大,怎么办呢?所以,我们对应 的MAC帧必须得对上提要求, 它抬头看了看IP,IP呀你发送的数据报不要太大,你要是发送太大,那你自己还要将其分成多片吧,要是发送太多,我在底层万一出现碰撞,就会导致我发送效率降低,因为你的问题,而导致我效率降低,所以,我要对你提要求,所以就有了MTU(最大传送单元)这样的概念!
》所以,我们又回答了一个问题,为什么我们曾经在讲IP那里的时候,为什么会有这样的规定呢?原因就在这。下一个问题,MTU应该是多少呢?一般是1500字节,也就是上层交给我们的数据不能超过1500字节。为什么是1500呢,这是研究出来的数据,它背后是论文证明。所以,我们的碰撞域呢,在物理上要减少我们的主机个数,在软件上要减少报文的大小,进而就能减少了。万一真的要是碰撞了,怎么办呢?我还会有一些碰撞避免的算法。碰撞避免呢,我们都是会随机上一段时间,然后再去重发这样的策略。
》我们将这部分搞定之后,我们就要花时间来谈一谈课件内容。
》认识MAC地址:
·MAC地址用来识别数据链路层中相连的节点;
·长度为48位, 及6个字节. 一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
·在网卡出厂时就确定了, 不能修改. mac地址通常是唯一的(虚拟机中的mac地址不是真实的mac地址, 可
能会冲突; 也有些网卡支持用户配置mac地址)

》对比理解MAC地址和IP地址
还是 [唐僧例子之白龙马]
IP地址描述的是路途总体的 起点 和 终点;
MAC地址描述的是路途上的每一个区间的起点和终点;

》认识MTU
·MTU相当于发快递时对包裹尺寸的限制. 这个限制是不同的数据链路对应的物理层, 产生的限制.(主要是因为不要数据报太大,导致在局域网内碰撞概率增加的问题)
·以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充
位;
·最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
·如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分
片(fragmentation); (我数据链路层根本不关心你IP层将数据分成多少层,我只关心你交给我的数据不要超过MTU)
·不同的数据链路层标准的MTU是不同的;

》MTU对IP协议的影响
·由于数据链路层MTU的限制, 对于较大的IP数据包要进行分包.
·将较大的IP包分成多个小包, 并给每个小包打上标签;
·每个小包IP协议头的 16位标识(id) 都是相同的;
·每个小包的IP协议头的3位标志字段中, 第2位置为0, 表示允许分片, 第3位来表示结束标记(当前是否是最后一个小包, 是的话置为1, 否则置为0);
·到达对端时再将这些小包, 会按顺序重组, 拼装到一起返回给传输层;
·一旦这些小包中任意一个小包丢失, 接收端的重组就会失败. 但是IP层不会负责重新传输数据
》我们引入一个问题,数据链路层规定大小是MTU1500字节,就要求IP进行分片,IP一脸嫌弃和无奈,你这个底层协议老是给我提要求,我看你特别不爽,无可奈何的就是,我又没有办法,我只能给你分片,更重要的是,我给你发送数据的单包数据大小不是由我决定的,我也有上司,我的上司是UDP/TCP,它们来决定单包数据大小。所以IP就特别难受,两头受气。MTU说,数据链路层我不管,1500以内我就发,超过1500我就不管,TCP就拿着一大堆数据说,我不管,4096个字节你给我发过去,IP被逼着没什么办法,行吧,那我就自己分片吧。IP就特别想中层领导,底层说没办法,干不了,上层必须让你把这个任务做了,所以就很难受。所以怎么办呢?IP实在扛不住了,就大声对MAC帧说,你的这个要求能不能变一变,这是硬件上规定的,我改不了。IP既然对底下提不了要求,那就给老板说,能不能每一次派任务给我的时候,是小一点任务,不要太大,不然我还要分片,分片时,一个人任务出问题,就导致整个任务出问题。老板一想,确实是这样,做事效率太低,会影响到我,比如对产品经理说做一个微信,如果做不出来,影响的就是半年时间还投入了那么多的钱,那我就把需求写成只具有聊天功能的工具,那么就能完成了。同样的,TCP协议也会考虑,如果我让IP过度的去进行分片,如果丢包了,会影响我,让我进行重发,你的要求我听到了,所以我可以帮你这么干。所以数据发送之前,转发的时候,一定是数据报的大小不是由MAC帧决定,它只是提标准,更不由IP决定,它只是一个跑腿的,而是由TCP决定,由传输层决定,数据报发多少,由谁来发,是由传输层决定的。所以传输层决定我们IP报文要不要分片的情况。
》所以这个故事告诉我们什么道理呢?为什么IP要求不了MAC帧呢?原因是IP没有和MAC帧谈判的筹码,因为站在MAC帧层面上提要求,你不光没有我的筹码,你还得求我帮你办事,所以IP受制于MAC帧的,那为什么IP就能让TCP妥协,让TCP去考虑它的感受呢?根本原因就是IP做事的好坏会影响上层,如果IP分片不影响上TCP传输,你IP再怎么分片,对我TCP来讲,不会帮你做任何事情。连我的网络协议栈也有人情世故在里面。
在这里插入图片描述
》貌似我们好像把我们整个通信的所有过程全部理顺了,我们复盘一下,看看是否真的就全部理顺了呢?现在已经有了一个关键的内容就是,我们能从A主机送到B主机,首先MAC帧能够帮我们从这一跳到那一跳,能这一跳,那么往后的每一跳就都能跳了。都能跳之后,I P地址给我们提供路径选择与目标,让我们进行路径路由,将我们的数据能够路由到目标主机C。当我们体会到这一点之后,我们就已经具备了一种能力,就是将数据从A送到C了,这个能力是由IP + MAC帧共同完成的,这就完了吗?并没有,因为在路由的时候呢,有可能因为网络拥塞的问题,或者路由器故障的问题导致丢包,丢包怎么办呢?由我们的上层TCP发送策略,诸如超时重传、滑动窗口来对我们数据报进行重传,在进行重传的时候就是在使用底层协议所匹配的能力。我们链路层解决的是最底层数据报跳转的问题,网络层提供路径转发和目的,将数据可以跨网络从A送到主机C;传输层就可以将我们的网络呢,直接进行在我们数据报丢包的时候呢,可以进行重传,给我们提供的是策略。所以,传输层提供可靠性策略,网络层提供路径选择和目标,链路层提供下一跳转发的能力。所以,网络层+链路层提供的就是从A送到B的能力,传输层+网络层+链路层共同提供的就是将我们的数据可靠的跨网络送到目标主机,一切都很完美,看似没有什么问题。
》可是呢,我们还有一个潜在的问题我们还没有谈,当一个数据报被千里迢迢送到了某一个子网入口路由器D,它要从路由器D交给主机C。目前路由器D收到的报文里面,首先在无数次路径转发的时候,源、目的MAC地址一直在被替换,源IP地址可能是会被替换(前面是有讲过家用路由器将数据转发给运营商的路由器),但是目的IP地址是一直都不变的。可是我路由器D收到数据报的时候,我只知道我要去的目标主机C的IP地址,我并不知道主机C的MAC地址呀!比如说我们主机B在很远的地方北京,而主机C在内蒙。其中在进行访问的时候呢,我们主机B不可能知道全网内,很远的MAC地址,没法传过去,所以当我们走到入口路由器D时候,我们要认识到,我们只知道目标主机的目的IP,但是你要从路由器D交给主机C,根据我们链路层协议,你必须被封装成为一个MAC帧,然后才能交给物理层再进行向主机C进行转发。所以呢,必须得被封装成MAC帧,那么就必须得知道对方的MAC地址,所以就有一个问题,当我们的数据到达了对方的子网当中的入口路由器的时候,我怎么把数据报转给目标主机C呢,这是其一;其二呢,你刚刚给我讲过一个场景就是数据从M1可以直接M5(他们在同一个局域网内哈),所以M1发给M5的时候,封装MAC帧的时候,就可以填源MAC地址M1,目的MAD地址M5,可是M1你怎么知道M5对应的MAC地址是多少呢?也就是最终的问题是,我们如何确认,如何在同一个局域网中,目标主机的MAC地址是多少呢?
》所以呢,我们会发现这个问题你不解决可以吗?答案是:其实是有解决方案,一会儿在讲局域网是有广播的,但是广播太low了,我们争取要把数据一对一的发给目标主机,所以这是一个问题,你还必须得解决。
》所以,我们还需要有一种协议,就是ARP协议:地址解析协议,将IP转成MAC地址!在正式谈ARP之前呢,还需要给大家说一下。当我们的数据报到达入口路由器D时,你心里面一定要能够想明白,当我们到达了目标网络的入口路由器时,目标网络的入口路由器也属于局域网内的一台主机,而同一个局域网内的主机是可以互相直接通信的,所以路由器不知道C的MAC地址,但是它可以有方法让目标主机C得到消息,所以这点要注意。
》下面呢,我们要重点谈一谈下一个协议,ARP协议!
在这里插入图片描述
ARP协议
属于数据链路层,是在局域网当中有效的协议
。那么它和我们的MAC帧协议是不是属于同层协议呢?从层划分的话,那确实是的,但是同层协议内部有多个协议话的,那么协议和协议也有上下关系,其中ARP协议是属于MAC帧协议的上层。也就是我们的MAC帧它脑袋上有一个协议就是ARP协议,但是它们属于同层协议。比如你们在一个公司里面是研发一组,你们某个小组内部是有领导管着,是有上下级关系的。我们把话再说直白一点,意思就是说,我们接下来要讲的协议ARP也有可能是MAC帧。我们整个ARP协议对应的报文格式呢,最终也属于我们对应的MAC帧对应的有效载荷。除了数据是IP报文需要向IP层交付,它也有一些管理协议,比如ARP协议呢,它可能也会充当MAC帧的有效载荷。
在这里插入图片描述
》所以接下来呢,对我们来讲,我们要能够意识到,我发出的MAC帧有可能是一个数据帧,有可能是一个ARP管理的帧,所以它有如上很多字段。
》其中“以太网目的地址”,我们在发送的时候,我们的主机A只知道我们对应的主机B的IP地址,并不知道MAC地址。所以主机A呢,是不知道主机B的MAC地址,怎么办呢?以太网的目的地址,比如说我的主机A要给主机B发消息,发ARP的时候,这个以太网目的地址能不能知道呢?答案是:我们不知道,如果我们知道了,就不会ARP了,就直接将MAC帧数据发过去了,但是现在我们不知道,不知道没关系,我们把以太网目的地址填成位全FF…,全F就代表的是广播,也就是所有的主机都要收到,就是广播,以太网目的地址是6字节大小的话,也就是12个F。
》再下来就是“以太网源地址”。填的是自己的,比如说是MACA,谁发起ARP请求,就将自己的MAC地址填充进去。
》再下面就是“帧类型”字段。一般是固定的,它代表的含义就是,ARP协议定制的时候呢,由于网络有可能是以太网,有可能是令牌环网,所以要甄别出来,当前网络是以太网还是令牌环网,所以他有一个硬件类型,就是链路层网络类型,1表示以太网。
在这里插入图片描述
》再下来就是“协议类型”字段。比如说0800代表的就是IP。这个字段意思就是说,我们需要地址转化,你给我什么类型的地址,所以如果协议类型是IP的话,那么我给你的就是IP地址,我想把IP地址转发成我们对应的呢0
其实“以太网目标地址、以太网源地址、帧类型”是不属于ARP协议的,课件有错误,剩下的字段是属于ARP协议的。其中,我们未来将我们的ARP协议封装成MAC帧的时候,其中MAC帧协议(以太网帧格式)对应的目的地址,我们是不知道的,那么其中我怎么知道,其实就相当于我们并不清楚对方主机的MAC地址是多少,所以我只能是填全FF…,就是广播。源MAC地址就是将数据报转发出去的主机的MAC地址。再下来以太网帧报头的“类型”字段,就是MAC帧的有效载荷,如果类型填的是0806,代表的就是ARP请求或者应答,所以类型这里呢,我们就填0806。当然这个字段呢,我们在向下交付时,底层的MAC帧会给我们填的,上面的图呢,没有画CRC,是要带上的!把这个搞定之后呢,我们再来看看,下面的图才是我们的ARP的报文格式。
在这里插入图片描述
》第一个呢,“ 硬件类型”字段。就是你现在转化的时候,底层的网络是什么网络类型的,那么就是对应的硬件类型,一般填的是1的话,表示的是以太网,我们今天就是以太网,那么硬件类型字段就是填的1。
》再下来字段就是,“协议类型”。你要得到对方主机的MAC地址,你给我什么呢?就是你,你通过我,想让我拿到哪一个主机的MAC地址,所以你得给我对方主机的IP地址,所以我们想给别人的事IP数据,那么“协议类型”字段,填的就是0800.未来可能会有IPV6等其他协议,这个协议类型也是可以变化的。
》再下来“硬件地址长度”字段。我们也知道,硬件长度一般是6字节,所以我们填的是6。
》“协议地址长度”字段呢,在IPV4这里也是固定的大小,就是4字节,填4就完事了。
》比较重要的是剩下的那几个字段。第一个呢,就是“发送端的以太网地址”。就是,是谁请求我们对方主机的MAC地址呢?发送方呢,是我们主机A,那就是填的A的MAC地址,就简写成MACA。
》再下来就是“发送端IP地址”字段。就是我这个主机,它的IP地址是多少呢?我自己的IP地址,我知道吗?我知道的,那么就是填IPA。
》再接下来呢,就是“目的以太网地址”。对方的MAC地址我知道吗?对不起,我不知道,我要是知道的话,我就不会发起所谓的ARP请求了,所以,我们填的是全FF…。
》再下面就是“目的IP地址”。我知道目的主机对应的IP地址吗?我必须得知道呀,知道的话,这个字段填充的就是IPB。
》也就是说呢,在做这个ARP协议表中呢,就知道对方主机的IP地址,然我们是想通过对方的IP地址得到对方的MAC地址。 那么我们就把这整个报文放到数据链路层,也就是放在MAC帧(以太网帧)的“数据”字段当中,然后将这个数据帧转出去,当数据帧在转的时候,它也不知道转给谁,所以MAC帧(以太网帧)的“目的地址(目的MAC地址)”填的就是全FF…。所以MAC帧在转发的时候,在局域网当中,以广播的形式被每一个主机都收到了。每一个主机收到,是不是都要对收到的MAC帧进行提取,它首先看到目的地址是全FF…,然后要不要处理呢?答案是:每一台主机都会进一步处理。因为这一个目的地址是广播的意思,每一个人都要进行处理,怎么办呢?所以,每一台主机都要再提取“类型”字段,发现时0806,所以每一个对应的主机呢,都要将MAC帧报文解开,也就是获取“数据”字段里面的内容,将“字段”交给MAC帧上层的ARP协议,也就是每一个主机都交给了自己的ARP层。所以现在开始,每一个主机都要处理自己的ARP数据了。
》来请问,每一个主机在处理的时候,是先看哪一个字段呢?假设我告诉大家,有一个ARP请求,我们假设是以太网,以太网协议类型肯定也要做检测,包括硬件长度和协议长度都是会看的,ARP协议格式的前面4个字段(硬件类型、协议类型、硬件地址长度、协议地址长度)我们基本上可以忽略了,因为这4个字段,在我们现在的网络环境当中呢, 就已经是标准内容,也就是说选的以太网、0x0800、6、4.
》接下来,假设是ARP请求,我们主机收到后会先看哪一个字段呢?答案是:是不是会先看一下,叫做目的IP地址,理论上是不是先看目的IP地址,因为它看目的IP地址,发现时IPB,其他主机分别是IPC、IPD、IPE等,由于目的IP地址是IPB,所以,所有的主机都会在ARP层对比出来,发现ARP请求不是发给自己的,所以每一个人都在ARP层将数据报丢弃了。问一下大家,如果C主机看了一下目的IP地址,经过对比,它肯定知道自己的IP地址,对比IP不是自己,所以ARP请求就直接被丢弃了,这次丢弃和上一次的丢弃一样吗?上一次指的是我们正常在局域网通信时候,主机丢弃数据报的情况,一样吗?我的问题是,现在有一个ARP请求,这个请求被所有主机一样也收到,收到之后,因为MAC帧的“目的地址”是全FF…,所以会继续根据“类型”字段,将“数据”向上交付给ARP层协议,通过获取ARP协议当中的“目的IP地址”,发现不是自己的IP地址,直接丢弃,这个丢弃一样吗?答案是:不一样!这次丢弃可不是在我们收到数据帧的时候,由于MAC帧的字段“目的地址”不是自己的MAC地址而丢弃,情况是不一样的,而发现是全FFF…然后交给ARP层后发现不是交给自己而丢弃的。所以每一层协议并不是在MAC帧协议这里丢弃的,而是在靠近上一次ARP层协议丢弃的,但是依旧是数据链路层,对于用户来讲也是令感知,感觉不到的哈。
》所以,经过目的地址对比之后呢,主机B发现是叫自己,主机B此时发现ARP请求是发给自己的,然后怎么办呢?然后B是不是要给A进行一个ARP的应答。应答什么呢?“硬件类型”字段,填的照样是我们对应的1,表示以太网;然后“协议类型”照样是0800;“硬件长度”是6,“协议长度”是4。“op”暂时不管。所以, 如果B要进行ARP应答,那么“发送端以太网地址”应该填多少呢?是不是要填自己的MACB呀!B主机在进行ARP应答的时候,“发送端以太网地址”填的就是MACB。因为B主机这次做的是ARP发送端,那么“发送端IP地址”填的就是IPB,然后“以太网的目的地址”填的是谁呢?它这次在应答时候知不知道我给A要进行应答呢?它是知道的,因为是A给它发送的MAC帧数据,A的MAC地址是填充到MAC帧协议里面的,所以他是能够拿到的,所“目的以太网地址”填的就是MACA;目的IP地址它知道吗?它能知道主机A的IP低呢?知道呀,因为主机A曾经是填写过自己的IP地址到ARP协议里面的!所以“目的IP地址”填的就是IPA。然后这个数据帧再进行向下封装,也就是回到了MAC帧格式了,需要填写MAC协议格式中的“目的地址(目标主机MAC地址)”,所以“目的地址”填的就是MACA了;然后“源地址(源MAC地址)”填的就是MACB了。
》所以,我们的B主机重新构建了ARP响应封装成MAC帧数据发送出去,那么局域网内的其他主机能收到吗?答案是:能收到。做MAC数据帧提取时候,还需要提取到ARP层协议吗?不需要了!因为B发送到MAC帧数据的“目的地址”明确填的是MACA,而不是全FF…!所以直接就将MAC帧数据丢弃了,不需要在ARP协议层将数据丢弃。所以,这次丢弃和上一次丢弃又有什么不一样呢?上一次指的就是ARP协议层丢弃,有什么不一样呢?这一次丢弃就是直接在MAC帧层丢弃了,并没有上传到ARP层,因为它知道,目的地址是确定的MACA,对比不是自己就直接丢弃了。当C、D、E等主机收到后丢弃,主机A收到数据帧的时候,发现目的地址是自己就发给自己的,然后根据MAC帧协议格式的“类型”字段,就将“数据”字段向上交付给ARP层协议,然后ARP层继续对数据进行解析处理,所以,A现在要拿到原先请求B的MAC地址的话,那么A主机此时在ARP协议里面提取什么呢?首先是会先看“发送端以太网地址”和“发送端的IP”,因为我得到ARP响应的时候,我直接提取B给我响应的ARP中的“发送端以太网地址”和“发送端端IP地址”,那么我们主机A呢,就能够立马得到我们的主机B的MAC地址和IP地址之间的映射关系了,一旦我拿到了主机B的MAC地址,我就直接向主机B再继续单向/定向的去发送一个新数据帧了,至此A就拿到主机B的MAC地址。
》换句话说呢,我们A和B在交换MAC地址的时候呢,是可以通过我们对应的ARP协议来进行交换的。但是上面有一个重要的问题,我们叫做“OP”字段。OP:任何一台主机,是不是都可能向别人发起ARP,是不是也就意味着,任何一台主机,可能同时在发起ARP,也可能在接收别人给它的ARP应答!这是第一点,这个很重要,这个也是我们理解ARP比较困难的地方,一会儿再将这几个字段快速的说一遍。第二个就更简单了,任何一台主机,都可能被发起ARP请求,这个也是很好理解的。也就是我一个主机,我可以向别人发起ARP请求,别人也可以向我发起ARP请求。所以,结合以上两点,我们任何一台主机,发出:一定发出的是ARP请求;接收的时候:1.别人向我发起的ARP请求;2.我向别人发起ARP请求时,得到的ARP响应。
》就相当于什么呢,只要是一台主机,它发出,一定是发出的ARP请求,它接收,它有可能接收别人向它发的ARP请求,也可能是它曾经发出去的ARP请求得到的ARP应答。所以,这里的
“OP”表示的究竟是ARP请求还是ARP应答
。所以就有了ARP协议里面的“OP”字段了。
》至此,我们将ARP协议的字段全部搞清楚,并且我们还粗粒度的把我们整个的ARP过程搞定,下面我们再综合性的来一个ARP发送过程。
》下面为了体现出ARP发送过程呢,此时给大家构建一个局域网,因为只考虑MAC帧。数据链路层被划分成两个层次,上面我们称作ARP层,下面我们称作MAC帧层。然后有若干台主机ABCDE等。
在这里插入图片描述
下面主机A发送一个报文,报文的目的IP是IPB,代表的就是我数据报要给B主机,怎么办呢?但是主机A并不知道主机B的MAC地址,怎么办呢?所以先做一件事情,填充ARP协议字段。“硬件类型”字段填的就是1;“协议类型”填的就是0800;“硬件长度”就是6;“协议长度”就是4。主机A要进行封装ARP请求,所以请求的话“OP”字段填的就是1;“发送端以太网地址”是不是就是MACA呀,也就是自己的MAC地址自己是知道的;下一个“发送端IP地址”是不是自己的IPA自己知道;“目的以太网地址”知道吗?不知道,那就填全FF…;“目的IP地址”知道吗?知道,IPB。所以这就叫做主机A构建可以个ARP请求,可是这个ARP请求不是直接发过去的,而是交付给下一层MAC帧协议层(以太网协议格式),也就是要封装MAC帧的报头,那么就要继续来填充“以太网目的地址”、“以太网源地址”、“类型”三个字段,以太网目的地址不知道就填全FF…表示广播,然后以太网源地址就是自己MACA;帧类型填的就是0806,代表的是ARP类型。至此我们就构建了一个ARP请求,并将其封装成了我们的MAC帧。
》最终发出去后,一定是会被我们的目标主机B拿到,但是B主机拿到同时,别的主机拿到了吗?他们都拿到了,他们拿到之后也是要处理的,那么就要对MAC帧协议进行解包,因为MAC帧协议的“目的以太网地址”填的是全FF…,表示广播,进而查看“类型”字段,发现是要交给上一层的ARP协议,然后ARP首先提取什么呢?我们现在要加一个,每一台主机提取的时候,先看哪个字段呢?这次是不是就要先看“OP”字段了呀,因为它要根据OP来得到,我们对应的是请求还是响应,得知“OP”是1,即请求,然后再看我们对应的“以太网目的IP”,填的是IPB,发现和自己对比不符合,因而将报文丢弃,也就是在ARP协议层将数据报丢弃的。
》我们其他的主机一定会收到,它也会向上交付,对比IP,看看是不是自己,不是就直接在ARP协议层直接丢弃了。于此同时,我们主机B是不是也要做同样的工作,它也要MAC帧数据的有效载荷交付给上一层ARP协议层,它当然也是先看“OP”字段,为1,代表的是请求,接下来再看目的IP地址,发现是自己IPB,谁请求呢?是MACA、IPA。我知道有人向我请求怎么办呢?第一,我知道别人发起ARP请求,向我要什么;第二,是谁在向我要信息,我也知道了。那么接下来我就要构建一个ARP应答。
》是不是接下来就是主机B来进行构建ARP应答了呀,怎么构建呢?我们继续。硬件类型填1,代表的是以太网、协议类型填的是0800,因为我们是IP之间转化、硬件长度填6、协议长度填4,还是原来的。这次“OP”填多少呢?这次是不是构建ARP应答呀,所以不再填1,而是填2,表示的是ARP应答;“发送端以太网地址”是不是就是MACB呀;“发送端IP地址”是不是填的就是IPB呀;“目的以太网地址”我主机B是不是知道呀,就是MACA呀;“目的IP地址”我是不是同样也知道呀,IPA。因为目的以太网IP地址表示的是要给主机A发,其中“目的以太网地址”、“目的IP地址”从哪里得到的呢?是不是曾经A主机发起的ARP请求里面可以获取到的呀。此时我们的主机B就将ARP应答构建好了,然后向下交付给MAC帧协议层。是不是又要填写MAC帧的协议报头呀,“目的以太网地址”我们知道吗?知道呀,这次就不是填的全FF…了,因为此时目的主机我们是十分了解的,直接填写MACA;这个消息是谁发的呢?当然是主机B呀,所以”源以太网地址“填的就是MACB;“类型”填的是0860表示ARP协议类型,至此MAC帧协议数据也封装好了,然后就是发送到网络里面了。
》此时其他的主机能收到吗?能收到,只不过提取MAC帧协议报头的时候,先是看到“目的以太网地址”填的是MACA,对比自己,不是,直接将报文丢弃了呀,也就是在MAC帧协议层就丢弃了!这也是我前面就问过,第一次丢弃和第二次丢弃一样吗?不一样!第一次是在ARP层将数据报丢弃, 第二次是在MAC帧层将数据报丢弃。所以,无论如何,A和B进行ARP的时候,其他主机其实并没有怎么参与。
》A也是收到B发出去的ARP的,它收到怎么办呢?是不是就提取MAC帧的数据报头呀,发现“目的以太网地址”填的是自己MACA,也就是发给自己的,接下来再看到“类型”是0806也就是ARP协议类型,然后解包向上交付有效载荷给ARP协议层。接下来主机A怎么办?是不是先看“OP”字段呀,先确认是别人请求我还是别人应答我,发现是2,即ARP应答,是不是我得到OP为2,意味着主机A曾经向别人发起过ARP请求,此时别人给我应答了呀,所以我主机A在知道得到的是应答,再获取发送端的以太网地址MACB、发送的IP地址IPB。我就知道了主机A曾经是要把哪一个IP地址与其对应的MAC地址我要获取到,所以此时主机A就得到了IPB对应的主机的MAC地址呀。当我得到了MAC地址,我再根据,知道目的MAC地址了,再把对应的报文重新封装成MAC帧,就能够定向的发给主机B了,此时就能正常的通信了。
》如上就是全过程的ARP通信。还没完,还差一些。ARP可能有点乱,一会儿请求,一会儿应答,但是你自己不要慌,你只要死死的把住讲的结论,你要么收,要么发。我只要收到ARP,那么要么是请求,要么就是应答,是通过“OP”字段来证明。这就完了吗?并没有,我们回过头再看看。
》比如说,路由器D千里迢迢的收到了一个数据报,它只知道这个报文所要发送的目的IP地址是主机C,目的IP地址是主机C的话,我们现在比较好奇的就是,路由器(主机)D它只知道它收到的报文将来是要给IP为C的主机,但是不知道主机C的MAC地址,也就没办法发,但是没关系,现在有了ARP。有了ARP,当我们路由器收到报文之后,如果并不知道目标主机的MAC地址,但是能不能确认目标主机就在此局域网当中呢?能的!因为我们是根据目的IP可以判断出来的。所以,我并不知道你是谁,但是我一定知道你就在,就好比你捡到一张学生卡,学号是13507,你不知道是谁的,但是我敢肯定是自己班级的学生,因为110开头的代表自己班级的开头。所以,我们并不清楚目标主机的MAC地址是多少,但是我们能够判断目标主机一定在当前网段内。当我们体会到这点时,然后,只要我知道它在,我们在通信之前呢,就先要进行ARP,通过ARP得到主机C的MAC地址,然后呢?我们紧接着再进行路上封装MAC帧,将其准确的交给主机C,至此就完成了数据报转发。
》接下来,我们还要进行思考一下,还有问题吗?是的。我们再想想,我们数据报已经到达了网络的入口路由器,我知道目标主机一定在当前的网段里面,所以我可以通过ARP。可是远端的主机非常高频的向主机B发送数据的话。也就是,很远的一台主机发过来一个数据报交给路由器C之后都要交给主机B,那么,难道我们发了100个报文,每次发报文的时候,都要遵守你前面说的,都要先进行ARP得到目标主机的MAC地址,然后再向主机B发送的过程吗?我的意思就是,我们主机A跨网络发送了大量数据,通过路由器D再送到我们主机B,发大量的数据,难道每一次数据报,都要先由路由器C发送ARP得到目标主机B的MAC地址然后再将数据报发给我们的主机B吗?这样是不是效率太低了呀。我们虽然不确定,但是我们可以
预测一下,这里的ARP肯定不是每一次都要发起的
,因为每一次都广播的话,成本是很高的,因为我们讲过是有数据碰撞的风险的,你随随便便在局域网广播消息,只会增加局域网当中通信碰撞概率,不利于我们局域网通信,所以,肯定不是每次都发送ARP的。那怎么办呢?好在,我们的主机接入到局域网,这个主机一般比较稳定,比如说在上直播课,接入的比特的局域网,然后呢,这个机器接入网络,可能一两天都不变,所以,对我们来讲,我们的ARP需要被缓存起来。由谁缓存起来呢?答案是:谁请求,谁缓存。缓存什么呢?缓存的是目的IP和目的MAC的映射关系。也就是一旦经过一次ARP得到目的IP和目的MAC映射关系,那么就会被缓存起来,往后再发送的第100、10000个报文直接拿着目的IP地址就能知道目的MAC地址,直接就能定向的送到目标主机了。
》可是如果我们保存起来了,如果主机B的MAC地址万一发生变化了,比如说这台机不联网退出了,重新又接入了一台主机,那么这个IP地址就被新主机拿到了,怎么办呢?此时就要给大家再说一个,就是暂时缓存,一般都是10几20分钟,是可以配置的。这个缓存是有时效的,比如说,你每次发一个消息,我就将数据报发送给对方主机了,能成功发送呢,就说明我的当前的缓存是有效的,但是如果发送的时候,发现要发送的目标主机连不通了,或者掉线了,长时间没人给目标主机发消息了,或者就是信息条目长时间没有被人用过,我们就可以将保存的信息给抹掉了,抹掉了有影响吗?没有,大不了再进行一次ARP嘛。所以ARP既要被保存起来,也要一定能够更新,因为我们局域网当中的主机在不断的变化,因为局域网内的IP是共享的,所以当你不用这个IP的时候,你的路由器是会自动回收你的IP,当你这个主机不用的时候,别的主机再接进来的时候,你的路由器会重新再进行给这个主机发送ARP,然后调整IP地址和MAC地址之间的映射。这个呢,我们称之为ARP缓存表,如果我们的路由表一样,它是在我们的系统当中存在的。
》大家不要把ARP过程,只是在入口路由器时,进行ARP到目标主机,有没有可能在别的局域网的时候的路由器也会进行ARP呢?是会的。所以,都可以在路上进行ARP,不是在一个局域网当中发生的,而是可能在每一个局域网当中发生。
》再问一个小问题,如果我们想获取局域网当中所有主机的MAC地址,我该怎么去获取呢?你想想局域网不会很大,如果我想获取我子网当中的每一个MAC地址,我们该怎么做呢?原理说一下,我们可以先# ifconfig查一查自己的IP地址和子网掩码,得到之后,我们是不是可以知道,我们当前局域网的网络号是多少呀,即IP地址同子网掩码进行按位与&就可以到网络号;然后主机号无非就是后面几位。假设当前的子网掩码是255.255.255.0,我的IP地址是192.168.3.10,我是不是就可以枚举出局域网当中的可能存在的IP呢?怎么做呢?是不是192.168.3.10—>192.168.3.[1, 255],我就能将我当前网段中的所有合法IP全部都枚举出来,有可能有的有,有的没有,但是没关系,接下来我们要做的是不是将所有的IP都访问一次,怎么访问呢?无非就是发送报文,最简单就是ping www.baidu.com(用“ping”)然后可以携带选项等,所以,我们可以将我们局域网当中的所有主机都ping一次,系统会自动的将ARP表缓存在我们的系统当中哈。
》我们继续,因为主机A要给主机B发消息,就要缓存主机B的MAC地址,对不对。所以主机A是会保 存主机B的MAC地址的。下面给大家提一下就行了。如果说中间有一台主机,这个主机是接入了局域网的,它先发起ARP,然后得到主机B的MAC地址,因为主机A曾经也发起过,所以也就同样有主机B的MAC地址。所以两台主机都拿到了主机B的MAC地址,接下来要做一件事情,我们中间的主机,疯狂的去向我们主机A,假设我们的主机A是路由器,中间这台机器疯狂的向我们的主机A发起ARP应答,它 疯狂发送,我是主机IPB,MAC地址是MACM,也就是说,中间这台机器,疯狂的向我们的主机A发送很多很多的ARP应答,用大量的ARP应答来冲击主机A的缓存,它发送ARP的时候发送的时候填的IP地址是IPB,但是MAC地址填的是MACM,也就是将MAC地址换成自己的了。因为此时有大量的ARP,主机A的缓存有个特点,因为IP地址与MAC地址映射的关系一直在变,所以就倒逼着这个缓存要缓存最新的映射关系。主机A很笨,它收到ARP报文说,自己IPB,MAC地址是MACM,此时我们主机A就建立,IPB:MACM的映射关系,此时主机A收到新的数据报的时候,它不会发给真正的主机B,而是发给中间主机M,中间M的主机一定是知道主机A的MAC地址,也一定知道主机B的MAC地址,所以,主机M将主机A发过来的数据转发给主机B就可以了。中间主机M用同样的套路,不断的向主机B发送ARP说,我是主机A,IPA,我的MAC地址是MACM,也就是用大量的ARP去冲击主机B(主机B的缓存表要被迫一直更新映射关系),此时主机B就维护了IPA:MACM的映射关系,那么它要发送数据给主机A的就发送给了中间主机M,此时主机M再将消息转发给主机A。此时呢,我们主机M就成功用这种方式成为了局域网当中的中间人!
》我要是成为了中间人,我要拿到你的数据不就随便拿捏嘛?你交给我的数据,我就直接把你的数据经过报文解析交付给我的上层,我拷贝一份再扔出去,我不就可以对数据做分析和解析,然后监听盗取你,这个我们称之为局域网中间人攻击法。所以我们就将知识连起来了,我们在https那里为了解决中间人攻击呢,我们发出去https报文是加密的,你没有密钥你中间就是摆设,你破解不了我的密文,你有证书也无法篡改,所以我们的小知识就连起来了。当然成为中间人还有很多方式,最简单最入门的就是打开手机热点给别人连接。
》至此我们的ARP全部讲完,我们网络的主体结构全部搭建完成,从应用层一直到我们的MAC帧,我们已经知道了数据的很多细节了。

我们一般为了避免数据报过大的问题呢,我们说了,谁说了算呢?当然是TCP说了算,那么我们要注意的一点就是,TCP怎么说了算呢,或者说是传输层说了算。
》首先MTU对UDP协议的影响:
·一旦UDP携带的数据超过1472(1500 - 20(IP首部) - 8(UDP首部)), 那么就会在网络层分成多个IP数据报.
这多个IP数据报有任意一个丢失, 都会引起接收端网络层重组失败. 那么这就意味着, 如果UDP数据报在
·网络层被分片, 整个数据被丢失的概率就大大增加了.
》MTU对我们的TCP协议的影响:影响也差不多,只不过TCP有重传,但是呢,我们还是尽量不想让他重传。
·TCP的一个数据报也不能无限大, 还是受制于MTU. TCP的单个数据报的最大消息长度, 称为MSS(Max
Segment Size);
·TCP在建立连接的过程中, 通信双方会进行MSS协商.
·最理想的情况下, MSS的值正好是在IP不会被分片处理的最大长度(这个长度仍然是受制于数据链路层的
MTU).
·双方在发送SYN的时候会在TCP头部写入自己能支持的MSS值.
·然后双方得知对方的MSS值之后, 选择较小的作为最终MSS.
·MSS的值就是在TCP首部的40字节变长选项中(kind = 2).
在这里插入图片描述
我们现在网络把应用层也写过了,面向字节流的概念我们也理解了,所以,我们再反向的去理解我们的序列化和反序列化和自定义协议我们都能理解,下面要重点谈的呢就叫做,如果让你去写一个套接字,先不考虑获取www.com获取网页,我们以前写套接字使用IP的,Clinet连你的IP之后呢,就可以发送消息了,实验也做过。现在呢,当我发消息的时候,包括建立链接的时候,整个通信过程你能不能给我介绍一下呢?
》也就是,**我知道目标主机的IP,如果我向对发送http或者其他协议的数据,最后拿到了一个结果,比如文字或者网页,请帮我描诉一下所有的通信过程。**一般回答这个答案呢,是可深可浅,可粗可细的。假设面试官问你,访问www.baidu.com,此时就拿到了百度的首页,请描述整个过程。因为是开放式问题,记住了没有标准答案,一般在C/C++上问的很少,因为在C/C++当中很容易得到标准答案,比如说智能指针怎么理解,我们讲的时候其实是很容易能够罗列出来的,但是Linux的开放性问题知识太发散了,不太好谈。没有标准答案,那么好的答案是什么样子的呢,是要有轮廓,有细节的。你应该先讲1.整体过程;2.细节阐述。
》所以,应该这么说,如果要考虑域名的话,那就是a.域名解析;得到目标主机的IP地址之后,要根据IP,b.建立链接TCP;建立好链接之后,我们就要进行请求了,那么c.客户端要先构建http请求;d.发送请求;请求一旦被对方收到之后呢,对方接下来就要进行e.解析请求;就要提取里面的报头,获取请求方法和URL,再下一步就是f.定位资源;将资源找到之后,我们就要进行g.构建响应;h.发送响应;我们的浏览器i.收到响应&&进行解析;j.解释HTML进行渲展现给用户。这就是先把轮廓给别人说出来,然后在这个轮廓当中呢,有相当多的知识点。然后要细节阐述的时候,可以和面试官沟通一下, 说自己,每一个过程都基本了解,我应该先说哪一部分呢?如果随便说说,你就把你觉得重要的点说说,比如说建立连接、构建请求、发送请求等。

我们接下来要说的内容呢,不是一个重点,并不影响我们使用,不是一个特别高频的话题,我们讲的时候,是以原理为主。 我们上面呢,把我们的MAC地址和ARP全部搞定,MAC地址用来解决数据从一个节点跳转到另一个节点的问题,它解决的是点到点的问题,其中我们的MAC地址通信原理呢,有碰撞域,碰撞检测和碰撞避免等话题。再下来呢就是ARP,它重点解决的就是在你得知对应主机IP地址情况下呢,如何获取对方MAC地址的问题,这个问题呢,其实是我们必须得考虑的,我们必须得知道对方的MAC地址,然后封装MAC帧才能更快速的通信。其实还有一个协议IARP没给大家说,因为它不常用,也非常简单,它就是你知道对方的MAC地址,但是你并不知道对方的IP地址,那么你就可以根据MAC地址来索要IP地址,是ARP理解成本高呢,还是IARP理解成本简单呢?IARP是如何将MAC地址转换成IP呢?IARP是知道的你MAC地址,要你的IP地址,很显然,IARP在理解成本上只会更低,因为我已经知道你的MAC地址,而且IARP是在我们局域网当中存在的,我都知道你的MAC地址,我想要你的IP地址,直接封装MAC帧,然后直接向你点对点发起IARP请求,你给我响应的时候给我带上你的IP地址就行了,所以IARP要比ARP简单。
》下面呢,我们进入下一个话题,DNS。DNS就叫做域名解析,只有一点点。关于域名解析理解起来并不难理解,一般我们在访问某些网站的时候,我们都知道,实际上计算机在识别目标服务器的时候他必须得知道目标服务器的IP地址,而不是只知道对方的域名,实际上单独的域名是没有意义的,我们必须得知道对方的IP地址才能访问目标网站,但是IP地址是数字,在我们互联网进行商业推广呢,IP地址是特别不方便的,假设我们协议190.168.23.1IP是阿里巴巴的IP,假如我把IP发给你,你压根不知道这是什么东西。
》如果是域名的话,我们只要输入www.alibaba.com,所以域名本质上是为了让人们使用互联网服务的时候,去定位某些服务更方便。
》下面呢,给大家重点来谈一谈域名解析的价值。你不是说过域名解析可以进行快速商业化嘛,是的,但是域名解析还有一些其他用途,包括我们很多大的互联网公司,对它们来讲的话,域名可能是不止一个域名。
》一般大公司对域名的使用呢,并不是我们想的那么简单,就是直接将域名访问到对应的服务,可以呀,直接让我们访问就行了,但是呢,要说一下,一般大公司呢,有的甚至几十上百万的机器,然后将其分别放在不同的机房。假设A公司在北京有、内蒙古有、贵州有自己的机房,现在3个机房都可以提供等量的某种服务。然后呢,它的机房一旦推出来了,怎么样能够让他的服务尽快的被我们客户所访问呢?比如我们只有一个www.xxx.com那么就只有一个域名,可是呢现在是有3个机房的,所以这家公司呢,为了能够不让上亿的用户都跑到一个机房,那么其他两个机房闲着没事干,那是不是压力就很大呀。所以,在公司内部的域名当中呢,可以携带自己的子域名或者IP地址,然后在域名解析的时候,比如你www.xxxx.com,最后解析出来访问的可能有好几种对应的IP地址,这几种IP到达客户端,它可以随机的将同一个域名所匹配的多个IP当中随机的一个给用户,那么用户又可能访问北京,有可能访问内蒙古、贵州。所以,就可以通过域名解析来实现机房之间的负载均衡。要不然只有一个IP的话,大量的请求都涌向一个机房,光有IP是只能够访问某一个网段内的主机,有时候我们的机房遍布全国各地,那么大家所划分的网段肯定是不一样的。所以IP地址绑死了,那么就只能是某一个区域进行访问。
》所以,公司有扩展机房的能力,都在域名解析层面上增加自己的负载均衡。

下面我们再谈下一个话题,我们就要回答一个大家之前碰到的一个问题:我们在讲IP的时候,有一个话题我们没有解释,就是在讲运营商的时候。我们说过,现在IP资源是严重不足的,IP地址严重不足的表现就是,有很多的设备到要入网的问题,其中呢,我们在家里面连接网络的时候,是人家设计过的,这部分网络,我们称之为私有IP。私有IP是不能出现在公网上的,我们相当于把42亿多个IP地址切成了两大块,公有IP和私有IP,其中私有IP是专门用来组建局域网,这个局域网的工作呢,可能你自己也做过,你将自己的设备打开,打开热点,这就是你开了一个局域网,然后你买了根光纤,入网连接到三大运营商的带宽服务上,我们就可以进网访问了。
在这里插入图片描述
》其中无论是你自己组建,还是运营商帮我们组建,我们大部分人全都是用的局域网。公网资源是被全人类所共享的,我们国家的当然是被三大运营商所使用。我们使用的基本上都是私有IP,它可以在一个局域网内出现,也可以在另外一个局域网内出现,也就是私有IP是可以重复的。但是同一个局域网当中是不允许出现私有IP相同的,不同的局域网是可以有相同的IP地址的,只要能够保证在局域网内是唯一性就可以。
》当我们访问外网的时候,我们其实就是出去了,访问到了外网的服务器了,但是,对不起,因为你用的是私有IP地址,先暂且说你能不能出现的问题,即便你出去了,你请求完服务,人家给你响应的是,人家也没有办法根据你的私有IP找到你这台机器,因为你使用的私有IP,全网当中可能存在上万上百万个和你相同的私有IP地址,所以外网主机是没办法找到我们的。
》所以,我们说过的第一个结论就是,私有IP必须经过路由器设备,尤其是运营商路由器设备的时候,它要进行不断的源IP地址替换,把我们源IP地址替换成所经过的路由器的WAN口IP,一路替换上去呢,最后出来的时候,报文上携带的WAN口IP呢,就是我们运营商的出口路由器,当我们请求的服务器进行返回响应的时候,是能够知道如何将数据返回到我们的运营商路由器。我们上次就讲到这,没有讲响应回来的过程。也就是,我们只讲了如何出去的问题,一个结论:把我们数据报当中的源IP地址一路替换成所经过的路由器的WAN口IP地址,就可以完成访问我们的目标服务器了。但是,如何回来呢?这就是我们接下来要讲的,如何回来,我们就要谈一个话题,就是,NAPT!我们称作NAT转化表。
》下面先念一念课件当中的NAT技术或技术细节,我们先说完,然后我们在讲解一下,再谈一谈它。
》之前我们讨论了, IPv4协议中, IP地址数量不充足的问题;
》NAT技术当前解决IP地址不够用的主要手段, 是路由器的一个重要功能;现在的路由器基本上都要支持NAT技术,因为现在尤其是局域网络,都是使用的公网IP,没有使用私网IP。
·NAT能够将私有IP对外通信时转为全局IP. 也就是就是一种将私有IP和全局IP相互转化的技术方法:
·很多学校, 家庭, 公司内部采用每个终端设置私有IP, 而在路由器或必要的服务器上设置全局IP;就是在路由器上呢,你有必要设置WAN口IP,不一定要是公网IP,因为运营商有可能组建进一步的局域网,所以在路由器上会设置自己的WAN口IP,用来成为我们访问外网的一个出口。
·全局IP要求唯一, 其实指的就是我们的公网IP,但是私有IP不需要; 在不同的局域网中出现相同的私有IP是完全不影响的
》我们给一个结论,公网IP全球唯一,私有IP在自己所属的网段内唯一。因为私有IP在自己所属的网段内唯一呢,所以不同的局域网出现相同的私有IP是完全没有影响的。下面一张图其实就我们数据报出去过程。
在这里插入图片描述
客户端的IP地址分别都标明了,它们在将数据报发出去的时候,左侧局域网,右侧公网,它的数据报当中是有源IP地址和目的IP地址,其中经过路由器的时候呢,是会转化源IP地址,首先目的IP地址是绝对不能变的。所以在进行转化的时候呢,把源IP地址直接替换了,转化成我们的公网IP,目标IP不变,源IP地址就变成了202.244.174.37。那么其中对我们来讲呢,我们就完成了IP地址的相关替换功能,替换成功后呢,就可以访问到我们的目标服务器了,然后目标服务器可以反向的将响应传回来。当然我们讲的是出去的问题,这个早就说过了,本质上就是将数据报的源IP替换成路由器的WAN口IP,那么就出去了。
》下面呢,我们就要谈怎么回来呢?
》那么问题来了, 如果局域网内, 有多个主机都访问同一个外网服务器, 那么对于服务器返回的数据中, 目的IP都是相同的. 那么NAT路由器如何判定将这个数据包转发给哪个局域网的主机? 举个例子,主机A、B、C都要访问外网的服务器,因为他们在访问的时候呢,源IP都会被替换成202.244.174.37这么一个IP地址,虽然我们的服务器收到了三个数据报,但是在服务器看来都是一个NAT路由器给我的,所以服务器给响应的时候,就将数据交给了路由器,可是呢,在这个NAT路由器收到了三个响应的时候,它很尴尬,我应该怎么把哪一个响应给哪一个请求呢?所以,回来的话,服务器将数据给了我们运营商的出口路由器,但是下来该怎么继续给呢?
》这里就要做一个NAT转化,当我们在进行公网访问的时候呢,我们路由器要去给我们维护一张转化表。首先在看转化表的时候给大家说一下,在进行源IP地址替换的时候,可不仅仅是把源IP替换,源端口想替换也是能够替换的,只要你最后给我能够恢复出来就行了。所以,这里的路由器呢,在出去访问外网服务器的时候呢,它不仅仅将你的源IP做了转化,还在自身维护了一张外部请求和内部主机之间对应的一张映射关系。假设客户端A的目标地址是我们对应的163.221.120.9,源地址是10.0.0.10,端口号是1025。此时我们的路由器将数据报拿到了,那么他就要做源IP地址的相关转化,怎么转呢,当然是报文的源IP地址转化成了202.244.174.37 ,端口号1025不变。它除了转化呢,它还在自己的转化表当中新建了一个KV的映射关系,也就是,源IP在内网当中对应的套接字对,也就是你的报文的原始IP10.0.0.10:1025,目的IP163.221.120.9:80,也就是你的数据报去的目的IP和目的端口号也都有,然后把转化表的左侧复制,在右侧粘贴,就将右侧的源IP地址替换成202.244.174.37,次至此就建立了图下所示的映射关系。
在这里插入图片描述
接下来怎么办呢,如果接下来还有客户端B,是10.0.0.11也是访问同一个外网的服务器,只不过它的主机号是10,那么路由器也将它的源IP:端口号和目的IP:端口号弄成大字符串保存在转换表里面,也同样的复制左侧,粘贴到到右侧,将源IP进行替换成202.244.174.37。因为A、B使用的源IP和源端口号一样,一样没有关系,我们将源端口号也换掉,换成1026,所以此时也给你客户B建立了从左向右的转换表,所以,当对外进行响应回来的时候,服务器收到我们的请求,当回来的时候,一定是从右向左查询的,也就是回来的时候,可以反向查表,根据目的IP地址,也就是路由器的WAN口地址,虽然是一样没关系,但是端口号是不一样的!那么是不是就可以查找到曾经是被哪一个转换过来的呀,那么再把响应报文当中的目的IP地址再更换成左侧的源IP地址,进而将报文交给我们内网的主机。
》因为源IP:源端口port,目的IP:目的端口port是在局域网当中能够标定的唯一一个链接,所以这么一个四元组能够标定客户端A到路由器的唯一性,右侧的四元组又可以标定路由器到外网服务器的唯一性,所以只要饭回来的时候,他们两个左侧和右侧实现互为Key值的效果。
》所以,在我们路由器内部进行转化时,每一个你发出去的报文当中,如果必要,它会根据你要请求的TCP/IP协议当中的四元组,替换成,目的IP/端口不变,将源IP或者源端口号port做更改,更改之后呢,就形成了从左向右具有唯一性Key值能够找到右侧,从右向左,也能够唯一性的找到左侧。那么它们是不是互为键值呀,那么就会在NAT转化的时候,维护这么一张表,当报文进去或出去的时候就可以快速的进行我们的转化,这种技术我们就称作NAT技术,这张表我们叫做NAPT。
》有人说如果现在局域网当中有大量的主机都向外去访问,那么不就是有海量的报文嘛,是不是每一张表都要维护呢?不要想多了,这个NAT映射表呢,一旦你想建立链接访问服务器的时候,你基本上的源 IP和源端口号port基本上是不变的。可以想一下写的聊天室,连上之后,源IP和端口号都是不变的,除非你重新发起链接,那么NAT重新帮你建立映射关系就可以,所以这就是NAPT,NAT转化表。
》这样的转化呢,我们就能做一件事情,当我们的数据报出去的时候,每一个节点路由器都会帮我们维护一个属于它的MAT转换表,当数据回来的时候,会不断的进行替换我们的目的IP和目的端口号Port,不断进入到我们内网当中去访问了。这就是NAT转化。
》所以,我们一般在组建局域网的时候呢,不要担心,路由器早就设置好了这么一套规则,帮我们进行从内网到外网,从外网到内网的转化。
》下面问大家一个问题,如果按你所说,我今天从来没访问过公网呢,但是我的客户端主机直接访问到外网服务器,那么我们的外网服务器能够直接访问到我们局域网当中的主机嘛?也就是我们现在局域网当中可以通过路由器做转发,访问到外网的服务器,那么反过来,外网的服务器能不能访问到我们局域网当中的主机呢?从目前来看上是不能的,为什么不能呢?很简单,因为在你的路由器当中,你静默处理没有访问外网的时候,路由器根本就没有建立你这个主机和外网服务器NAT转换表,所以外网服务器是无法访问到内网的,是无法渗透进来的。但是呢,现在也有一些主流的技术,将我们局域网公开,这种技术我们叫做NAT穿透。
》下面我们再谈一个话题,有人会说,这个东西很像是代理服务器,那么NAT和代理服务器是不是一回事呢?答案是,不是一回儿事。NAT在原理上有点像,但是实际上,他们的差别还是有点大的。那么我们先来谈一谈代理。
》一般常见的代理服务器呢,也就两种,第一种就是,你如果用校园网可能访问的时候会被拦截,那么学校是怎么做到的呢?当你们通过校园网访问百度、抖音的时候呢,并不是直接访问的百度,你们也访问不了,而是在学校内网当中会设置一个服务器,所有的学生从学校宿舍里面网口出来的网络请求都不是直接到外网的,都是直接推送到代理服务器的。 这么一个服务器它替你去进行访问百度,然后请求到之后,再把这个资源中转发给你,你对它的感知是零的,也就不知道它的存在,那么别人在你访问的时候给你设置一些规则,这个呢,我们就称之为,代理服务器,这个代理服务器离客户更近,它是替你这个客户来做一些代理服务的,我们称之为正向代理。它存在的意义是什么呢?1.对你的请求进行过滤或拦截;2.可以进行一定程度的提高效率,那么这个是从何谈起呢?比如说A同学看了一部电影,这个代理服务器呢会偷偷的将这个电影资源缓存起来,宿舍里面的另外一同学也想看这部电影,代理服务器说,你现在要访问这个资源,我没必要请求外网了,直接将资源给你。3.身份认证。比如说学校会有校园客户端,输入学号然后➕密码进行身份认证。4.一定程度保护了内网
》一般企业呢,有成百上千万个用户,可能随时随地访问机房,机房内有一些对外提供服务的服务器,每一台服务器都有自己提供服务能力的上限嘛,其中这些服务器构成了一个集群,客户通过域名解析获取IP地址进行访问服务器,那么作为机房内部的服务器,不能让用户直接渗透进来访问内部机器,因为用户一旦能访问内部的任意一台机器,也就意味着用户能够看到这些机器,那么就很容易出现安全问题,比如说一批用户定向的将所有数据流量打向同一台机器上,那么就会导致这台机器无法正常工作了。实际上集群对外提供服务的时候,是有一个外部服务器,它会将所有人的请求都收集上来,因为没有业务处理,所以它非常快,它会将所有的请求,以它内部相关的算法,帮我们去选择对应的一台机器,然后把对应的请求推送到特定的机器,然后再由机器返回给客户端。也就是说,外部的那一台服务器机器不对外提供服务,它接收到用户的请求之后,直接就将其交给内网当中的某台机器去处理,然后处理之后的结果交给对应的客户,至此就完成了我们所对应的,外部服务器就相当于是一个分配任务的,来了任务之后,它可以根据一些机器的压力情况来将任务分配给特定的主机,最后就能以整个集群的能力来应对大量用户的请求。所以这种外部服务器接收来自外部的请求,它可以均衡的将服务器请求打散到集群当中,这种服务器我们称之为,反向代理服务器。这种服务器呢,主要是用于接收用户请求,然后将请求均衡的交给集群内的某一台特定的主机。
》反向代理的意义,我们把压力均衡的交给后端的机器,我们称之为,1.负载均衡;如果把机器暴露给外部随便访问,因为访问的是客户,无法均衡的将服务放到机器上。还有一种设备就是防火墙(可能是软件可能是硬件),2.保证内网的安全;
》如上就是代理服务器。这是不是有些像NAT呢?是不是我们的请求过来了,都是交给另外一台主机进行帮我们处理呀,他们工作还不是一样的呀。实际上呢,差别挺大的。
》路由器往往都具备NAT设备的功能, 通过NAT设备进行中转, 完成子网设备和其他子网设备的通信过程.
》代理服务器看起来和NAT设备有一点像. 客户端向代理服务器发送请求, 代理服务器将请求转发给真正要请求的服务器; 服务器返回结果后, 代理服务器又把结果回传给客户端.
》那么NAT和代理服务器的区别有哪些呢?
·从应用上讲, NAT设备是网络基础设备之一, 解决的是IP不足的问题. 代理服务器则是更贴近具体应用, 比
·如通过代理服务器进行翻墙, 另外像迅游这样的加速器, 也是使用代理服务器.
·从底层实现上讲, NAT是工作在网络层, 直接对IP地址进行替换. 代理服务器往往工作在应用层.
·从使用范围上讲, NAT一般在局域网的出口部署, 代理服务器可以在局域网做, 也可以在广域网做, 也可以
跨网.
·从部署位置上看, NAT一般集成在防火墙, 路由器等硬件设备上, 代理服务器则是一个软件程序, 需要部署
在服务器上.
》代理服务器是一种应用比较广的技术.
·翻墙: 广域网中的代理.
·负载均衡: 局域网中的代理

我们写套接字的时候并不能绑定购买云服务器时候所设定的公网IP,为什么呢,因为我们使用的一台机器,可能根本就是一台机器,它可能只是云技术虚拟出来的配置资源,打包成产品交给你了。实际上它上面所示的公网IP实际上根本就不是公网IP,它也可能是虚拟出来的,然后你可以理解成公网iP就是代理服务器,我们访问的是内网当中的一台主机。所以我们在绑定bind()的时候,给我们用的是内网当中某一台代理服务器的IP,在内网当中我们用的时候,根本就不是展示给我们的公网IP,因为不是公网IP,所以,你就无法绑定。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值