移动端的网站建设,淘宝做网站退款,wordpress支付宝微信,微信商城小程序怎么开通目录
网络层与数据链路层
编辑
网络层
IP协议
IP的构成
TCP和IP各自解决什么问题#xff1f;
基本概念
协议头格式
协议头分析
如何分离与封装#xff1f;
如何分用(向上交付)#xff1f;
16位首部校验和
32位源IP和目的IP
4位版本
8位服务类型(Type Of…目录
网络层与数据链路层
编辑
网络层
IP协议
IP的构成
TCP和IP各自解决什么问题
基本概念
协议头格式
协议头分析
如何分离与封装
如何分用(向上交付)
16位首部校验和
32位源IP和目的IP
4位版本
8位服务类型(Type Of Service)
8位生存时间
分片问题
为什么会分片
网络层交给数据链路层的数据大小是有约束的。换言之如果IP报文太大该如何处理呢
为什么要在网络层进行分片
谁来进行分片组装呢
什么是分片
如何进行分片
组合问题
请问这个分片的过程传输层知道吗怎们在技术层面保证传输层不知道呢
这个分片的过程传输层需要知道吗
分片真的好吗
一旦分片之后万一有一个报文丢失了该怎么办呢
如果我压根就不想分片了谁说了算
16位标识
13位片偏移
分片后如何组装呢
我怎么知道有没有报文丢失了呢
3位标志
接收端如何得知报文是独立的还是一个分片的
ip分片丢包了如何重传呢
网段划分
如何分配IP地址呢
在局域网中分配IP的两种方式
关于网络划分和建设
网络划分本质
分类划分法
为什么分类要分ABCDE这样的类别呢
为什么ip划分是这种分类划分法呢
CIDR
特殊的IP地址
IP地址的数量限制
私有IP地址和公网IP地址
全世界有很多的私网ip这些ip够吗
对于运营商的理解
为什么中国有这么多的互联网公司呢
为什么互联网公司不做这些事情呢
运营商愿意去搭建基础设施吗
这些基础设施架设好了要不要回收成本呢
我可以上网的时候不给运营商交钱就想直接访问别人的服务器可能吗
为什你欠了话费不能给其他人打通电话但是你确能给运营商打通电话
实际生活中我们发现只要欠费了你自己是交不了的你必须得让你朋友交或者连上WiFi缴费为什么移动不把这个缴费的接口放开呢
回顾之前的子网划分
总结
客户的一个请求是如何转发给另外一个客户的呢
比如我想搜索我怎么把我的请求转发给百度呢
那么现在构建响应回来如何把数据准确的响应给用户呢
为什么私有ip不能出现在公网上
我能不能直接把消息转发给我的朋友呢
我想把我的数据直接通过运营商路由器去转发而不经过公网这能做到吗
浅谈墙
国内的互联网公司为什么不去国际上呢
路由
IP数据包的传输过程
为什么我经过不断的去查找路由表直接就可以不断的去跳转到下一跳然后找到目标网络呢
那么如何判定当前这个数据包该发送到哪里呢?
路由表生成算法
数据链路层
对比理解 数据链路层 和 网络层
你为什么要把数据包由路由器A交给路由器B呢
如何把数据包由路由器A转到路由器B呢
同一个局域网两台节点能直接通信吗
局域网通信
以太网的通信原理
以太网帧格式
如何分离报头和有效载荷(封装)
如何决定将自己的有效载荷交付给上一层
认识MAC地址
类型字段
CRC校验字段
再谈局域网
有效载荷
在局域网中做数据转发的时候是基于碰撞检查碰撞域这样的策略去做的所以为什么数据帧的物理层为什么要规定1500字节(虽然这个值可以改大也可以改小但是基本上都是1500)
认识MAC地址
对比理解MAC地址和IP地址
认识MTU
强制解调器是什么呢
MTU对IP协议的影响
如果在路上分片了接收端主机该如何合并呢
MTU对UDP协议的影响
MTU对于TCP协议的影响
路由器如何跳转到下一跳
ARP协议
如何在网段中通过ip地址获得该主机对应的mac地址
路由器D是如何知道主机B的ip地址呢
ARP协议的作用
ARP协议的工作流程
ARP数据报的格式
ARP传输过程
为什么收到ARP后要先看OP字段而不是看目的IP字段
主机A收到来自主机B的数据帧为什么不直接从以太网首部这里提取主机B的mac地址呢
主机A经过路径选择到达了入口路由器然后到达主机B难道每一次向主机B发消息都要进行ARP请求吗
ARP缓存表
我可以将这个ip和mac地址永久保存起来吗
如果我今天想知道和我处于同一个局域网内所有主机的mac地址怎么办呢
RARP
其他重要协议或技术
DNS(Domain Name System)
DNS背景
域名简介
ICMP协议
ICMP功能
ICMP的报文格式
ping命令
编辑
一个值得注意的坑
有些面试官可能会问: telnet是23端口, ssh是22端口, 那么ping是什么端口?
traceroute命令
NAT技术
NAT技术背景
NAT IP转换过程
转化实例
NAPT
转化实例
NAT为什么能延缓ip地址不足呢
如果客户端A从来没有访问过服务器服务器能否访问客户端A吗
浅谈虚拟机的网络连接模式
NAT技术的缺陷
NAT和代理服务器
代理服务器
正向代理
为什么要有个代理服务器呢
反向代理
那么NAT和代理服务器的区别有哪些呢?
翻墙的原理
背景
原理
我们一般在云服务器上是没有办法绑定自己的公网ip的为什么呢
为什么socket通信时服务端不能绑定云服务器的公网ip及为什么要绑定INADDR_ANY 网络层与数据链路层 我们学TCP的时候TCP说是把报文从我的服务端发送到了对端这真的是把TCP报文发送过去了吗 答案当然不是真实的网络通信时贯穿协议栈的是自顶向下的。就好比人不能直接从3楼直接凭空飞到对面的3楼而是必须得下楼再上楼才能过去。换言之TCP封装好的报文不是直接发出去的而是要将TCP的报文再次向下交付通过IP协议进行路由转发转发到目标主机。 当然难道是IP报文直接发出去的吗 答案也不是实际上底层的数据链路层到物理层真正的数据是在链路上跑经过各种硬件设备转发到了目标主机再进行自底向上交付到了你的网络或者传输层才能被对方收到。我们之前说的都是忽略了TCP下层的通信细节。所以当你学习当前层的时候要弱化下一层协议的猜测只是站在功能角度认为下层给我提供这样的功能了。 以主机B和主机C为例之前我们学习的只考虑主机B和主机CHTTP只考虑应用层传输层只考虑了主机B和主机C两端的问题路上的问题我们并没有考虑。如果你的报文要到主机C前提条件必须经过这么多路由器才能到达对端。
网络层
IP协议
IP的构成
IP网络号主机号。 从生活当中的例子引出 人分布在不同地区的比如你想去天安门广场是不是你就乘坐交通工具一次到位直接就到天安门广场门口实际并不是。比如你要去天安门别人问你去哪你首先说的是我要去北京。所以当你到达了北京你在乘坐北京内部的交通工具:地铁公交...然后在到达对应的景点。 再好比唐朝取经他永远说的是平僧自东土大唐而来要到西天拜佛求经。实际上去西天不是他的目的他正在要去的是到了西天以后在去大雷音寺然后在面见佛祖。 我们到北京到西天叫做先找到去的地点所在的网络号到了目标子网之后我们再在子网中找对应的主机号就好比到了天安门大雷音寺。剩下的工作就是封包解包就好比到了天安门广场的找到了某个导游到了大雷音寺找到了如来佛祖。这个就是应用层特定的一个人提供服务。 我们实际上路由查找的时候不是完全按照目标主机去找的而是先找网络号再找主机号。
TCP和IP各自解决什么问题 在自然世界中人类解决问题无非就是就解决两个问题决策问题和执行问题。 eg:你和你的朋友要吃饭就先决策中午吃啥决策好吃饺子让后去食堂吃饺子这就是执行。我们这个世界上永远是有人在做决策有人在做执行。当然对于人很多时候都是既做决策又做执行。 对于计算机决策和执行则是分开的。如果混在一起则导致业务逻辑非常的不好写非常混乱所以把他们分层之后进行所谓的逻辑层面的解耦能让我们的维护成本降低。 TCP层一定是将自己的报文交付给下层让IP进行路由转发的TCP是保证可靠性的IP是不保证可靠性的如果TCP是给我们提供一整套的保证可靠性和提高效率的策略的话IP则提供了一种能力将数据从A主机跨网络传送给主机B的能力。只有IP具备了这个能力TCP才能把报文交给IP然后封装上IP的报头进而把IP数据包从主机跨网络传送到主机B这个时候才有意义到达主机B之后在进行向上交付分用将对应的ip报头去掉再交付给TCP此时这个TCP才被主机B在传输层收到对应的数据。 比如你是学校的学生你的成绩非常好你考试的时候较大概率能考到满分你去考试的过程就是你去做执行的过程因为你要执行一次考试那么如何保证100%拿到满分呢 很显然单靠你自己是不行的而你有一个非常牛的爹你爹是学校的教务主管他能组织学校考试的时间地点甚至是重考。那么你就去考试如果你这次没考到满分你爹就给你单独组织一次重考如果还没满分就继续重考因为你有较大的概率能考到满分所以经过不断重复就可以让你100%考到满分。 其中你做的工作就是执行你爹做的工作就是做决策你爹给你的决策就是如果你没考到满分就让你再考一次上次没考满分的原因是因为你太着急了你爹就告诉你下次考试我给你延长时间上次考试是因为环境太吵影响到你了你爹就把场清了让你一个人考试。其中你爹给你提供一种不断让你试错的决策能力这个就相当于是TCP解决的。而你提供了一种能力不断进行考试有较大概率拿到满分这就叫做IP层解决的问题。 你告诉你爹没考满分是因为时间不够了你爹就把时间给你延长了这就叫做流量控制你上次考试是因为环境太吵了你爹就把场给你清了这就叫做拥塞控制。 换言之TCP和IP相比TCP更强调的是TCP给我们提供的一个一个的策略机制IP更强调的是将数据以较大概率从主机A送到主机B。IP重要的是执行能力它能帮你把数据从主机A送到主机B。较大概率意味着大部分情况下不会出错也就意味着IP层不提供可靠性机制你只需要把你的能力用好就行了。因为IP的脑袋上还有TCPTCP的超时重传就是IP没把数据传过去TCP就让IP在来一次超时重传快重传拥塞控制...所有的机制都是为了把数据包发到网络里出问题了底层交付给TCP层然后TCP层就让他们再来一次所以TCP给了IP压力让IP不断进行各种基于TCP策略之下的各种执行动作。
基本概念
主机: 配有IP地址, 也是会进行路由控制的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称;
后序文章中像用户具体使用的设备端到端的我们叫主机路上的这些点到点的路由器设备我们就叫节点。
协议头格式 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4. 4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大的数字是15, 因此IP头部最大长度是60字节. 8位服务类型(Type Of Service): 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要. 16位总长度(total length): IP数据报整体占多少个字节. 16位标识(id): 唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的. 3位标志字段: 第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示更多分片, 如果分片了的话, 最后一个分片置为1, 其他是0. 类似于一个结束标记. 13位分片偏移(framegament offffset): 是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了). 8位生存时间(Time To Live, TTL): 数据报到达目的地的最大报文跳数. 一般是64. 每次经过一个路由, TTL - 1, 一直减到0还没到达, 那么就丢弃了. 这个字段主要是用来防止出现路由循环 8位协议: 表示上层协议的类型 16位头部校验和: 使用CRC进行校验, 来鉴别头部是否损坏. 32位源地址和32位目标地址: 表示发送端和接收端. 选项字段(不定长, 最多40字节): 略
协议头分析
ip的标准报头长度20字节宽度32个比特位。也可以携带选项也有4位首部长度(单位也是4字节)所以我们立马想到TCP的报头。IP的报头风格和TCP一毛一样。所以我们学习的网络协议栈是用TCP/IP命名的因为从协议当中就能看出来TCP和IP的报头长度是一模一样的。当然细节肯定不一样。
如何分离与封装
因为有4位首部长度我们收到一个完整的IP数据包就可以无脑读取前20个字节然后提取4位首部长度确定它有没有选项没有选项剩下的就是有效载荷。这就做到了分离。
另外它还有16位的总长度。IP不是字节流的TCP是字节流的这个字节流是站在应用层HTTP的角度我们曾经写的套接字角度看待TCP它是字节流的。可是我们发现TCP底层用的IP它的报文也必须一个报文一个报文发出去只不过发出去之后在TCP那里组合起来交给TCP写到TCP的缓冲区里TCP是以流式的方式呈现给应用层的而底层还得是一个个报文。所以它有16位总长度。所以IP报文要交付给上层的UDP和TCP就也需要解决它自己的粘包问题所以它也需要把报文和报文之间的边界区分开。所以4位首部长度和16位总长度就能够区分自身报文的报头和有效载荷。
封装报头的时候有选项直接加选项报头多长就填4位首部长度有效载荷多长就填16位首部长度。
如何分用(向上交付)
IP解完包后如何将自己的有效载荷交给上层协议IP脑袋上是传输层是UDP或者TCP。ps:如果是原始套接字IP脑袋上可能就是应用层。
IP就可以通过8位协议做到将自己的有效载荷交付给上一层的哪个协议8位协议里面填充的就是上层的协议是谁。但是一个IP报文并没有能力知道自己要把数据交给谁。
8位协议字段站在一个收到报文的角度它可以根据8位协议字段决定这个数据应该交付给上层的谁。可是这个8位协议是谁填充的呢
是IP吗IP没和这个能力因为IP无法决定自己的有效载荷交付给谁。这个8位协议是上层填的如果是UDP填的8位协议写的就是UDP如果是TCP填的8位协议就填的是TCP。所以一个UDP的客户端是不能和TCP的服务端通信的因为所有的报文都是由上一层的TCP或者UDP交付给下一层IP的所以上层再交付的时候它要参与IP报头字段的填充上层TCP在填写8位协议时这个报文数据也一定是传给对方的TCP。换言之就是上层给他填写的这个8位协议所以到了对端对端就可以交付给对等的上层协议所以这里就不会出错了。所以8位协议用来解决分用问题。所以这也就是为什么UDP只能和UDP通信TCP只能和TCP通信因为上层交付给下层的协议报文8位协议填写的就是TCP或者UDP自己。
16位首部校验和
报文说白了就是光电信号在硬件上如果因为硬件故障导致报文出现了细微的比特位翻转把某些比特位由0置1由1置0这个报文就出问题了所以不光要保证字段要正确数据也要正确。你要保证正确就进行校验。通过校验和确认IP的组装情况。
32位源IP和目的IP
一个报文就得告诉我你从哪来要到哪去。 唐朝取经他永远说的是平僧自东土大唐而来要到西天拜佛求经。 源IP和目的IP就是东土大唐和西天。
IP解决的就是把数据从一个主机到另外一个主机。解决的就是机器到机器的问题。TCP和UDP里携带的是端口号它要解决的就是从主机上把数据交付给应用的问题。
4位版本
基本上没意义一般是IPV4。
注意这个4位版本不能填写IPV6IPV4表示的ip地址是32个比特位。IPV6表示的ip地址是128个比特位。IPV4和IPV6是不兼容的。网络世界已经通过IPV4构建起来了IPV6又没有构建起来又和老的IPV4不兼容此时就很糟糕没有办法统一在全网中切换到IPV6只能慢慢迁移。现在引入IPV6只能是推到重来有些公司组建机房天然就用IPV6相当于内网是IPV6通信外网是IPV4。实际上双方ip地址解耦是通过数据解耦的相当于我给你发数据你在内部处理你的我路由我的互不干扰。所以这里的4位版本没有意义就是IPV4IPV6就是另外一套协议了。未来是有可能都是IPV6的但是还早不兼容导致迁移的成本非常高所以只能是在有新的网络设施架设起来的时候采用IPV6当网络世界的基础设施使用IPV6的设施变的非常多的时候IPV4使用比重降的比较低的程度下这个时候才可能用规模效应挤压IPV4的市场让IPV4退出历史舞台现在还早预计未来几十年IPV4和IPV6都是共存的状态。
8位服务类型(Type Of Service)
3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于 ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要. 这个东西正常情况下我们一般不太用一般是OS或者你自己实际使用的时候需要用一些新的选项来设置它一般我们默认就可以了。eg:你将来发送数据的时候转发路径A丢包的概率非常大但是这个路径它短非常快。路径B它虽然慢但是它丢包的概率低。所以用户选择了最小延迟你就只能走路径A。IP层的数据包已经是准备上网络的一个报文了所以在路上的时候就和你去考试一样你每次考试的时候就给自己定策略这次我要做第一个交卷子的(最小延迟)这一次我要做检查卷子次数最多的人(可靠性)这一次我要做考试成绩最高的人(最大吞吐量);这次考试别人用钢笔我用铅笔(最小成本)用成本最小的方式考试。因为报文在网络中要面对复杂的网络情况所以IP可能会给你提供各种策略让你进行数据包的一个处理。这些标记位不仅仅是给主机去看的实际上是给中间路由器转发的时候看的路由器发现这货要最小延迟我就尽快给他交付如果要可靠性就选择一条丢包概率最低的一条路径...8位生存时间
一个网络IP报文它是在网络里要进行转发的一会在一个路由器里排队一会在另一个路由器里准备发送一会在这个报文可能在网络中跑在网线里面从一个主机交付给另一个主机总之这个报文是要经过一个一个节点的。我们把一个数据包从一台节点交付给下一个节点我们称之为将数据包跳转到下一跳。一个报文可能经过多个路由器的跳转但是网络世界太大了每个路由器都有自己搭载的路由算法大家的路由器厂商算法包括这个算法编码实现的程序员bug的多少都不一样所以网络转发是一个很复杂的过程但是总是架不住有些数据包。eg:有些程序员写的路由转发代码有bug就导致一个报文在路由器中一直跳转此时就导致一个报文在多个路由器之间来回游离式的转发这种情况就可能会存在尤其是这个数据包的目标主机早就没了比如说我刚发出去一个报文这个数据包还在路上的时候源主机和目标主机就关了。此时这个报文就在路上就没爹没娘没开始没结束开始游离式的转发。如果这个报文最后到了目标网络发现目标主机已经没了那这个报文最后被丢弃到还好。如果因为网络太复杂导致网络里面出现了一些游离报文长时间无法找到目标主机甚至形成一种环路情况那这个报文就天天转来转去每转一次就消耗点资源如果是这样这个报文永远不消失因为网络节点一直是加电状态我们有集线器一直做信号放大所以这里的数据包一直在网络里跑时间一久我们的网络基础设施跑上10年20年我们的网络里出现这种大量的游离报文那我们就还得定期的清理游离报文这样的话成本太高所以IP设置了一个TTL生存时间这个概念就是每经过一跳路由器(每经过一个节点)TTL减减当TTL减减为0时这个数据包不在被转发就直接丢弃了所以数据包就和人一样具有了一定的生命。我们的一个数据包经过特定的路由器转发还没有到目标主机那么这个报文就只能被丢弃了一旦被丢弃一旦你在想发你只能把TTL生存时间设置的更长一些。在IP报文里面源IP和目的IP是最重要的因为报文在路上转发的时候大部分我们所考虑使用的字段就是这个两个源IP和目的IP如果再要挑一个重点字段一个报文在转发的时候最重要的就是目的IP这个字段对比其他字段就相当于一个王者带一堆青铜。 分片问题
分片是在路径转发过程之中几乎在每一个路由器每一个路上节点都有可能发生一个叫做IP分片的问题所以对我们来讲我们就要意识到它可能在哪都能进行分片。为了方便理解博主就直接在发送数据的时候发送主机可以尝试一下分片接收主机可以尝试下组装我们可以不考虑路上的一些特殊情况。虽然接下来讨论的是IP报文分片的一个问题但是我们也仅仅是站在报头的角度去理解分片。我们虽说在讨论分片但是IP分片不是大多数情况。分片也是一种特殊的情况我们的IP包含了这样的报头这样的报头往往在很多时候都是些常规的填充而不会填充成我们需要分片这样的情况但是我们得了解一下。为什么会分片 正常情况下应用层传下来的一个数据就可以交付给传输层传输层添加上自己的报头然后交付给网络层网络层添加上自己的报头然后交付给数据链路层。报文不断向下交付过程我们称之为封装的过程我们既然称其为封装的过程我们的网络层将来把他的报头在内也是需要向下交付封装的。 但是数据链路层有一个规定数据链路层一次可以往网络里发送的数据大小是有限制的我们称之为MTU。MTU在绝大多数主机当中都设置为1500字节。 mtu表示最大传输单元就是1500。 网络层交给数据链路层的数据大小是有约束的。换言之如果IP报文太大该如何处理呢
你现在MTU底层的协议告诉我我们的数据链路层最多能接收1500字节可是网络层交给你2000字节那么此时数据链路层该怎么处理呢或者网络层IP协议该如何处理呢
比如说你今天给你朋友邮寄了一台台式机里面有主机显示屏键盘鼠标你去把你的这一批设备拿到快递公司你给快递公司说能不能把我这一批东西邮寄到北京。快递公司告诉你对不起我们每次单个快递包只能是5千克你这个电脑是15千克得分3个包裹。因为快递公司单个包裹的重量限定此时就需要你把你要发送的资源进行分包请问这个分包工作由谁来做比较好呢
为什么要在网络层进行分片
正常情况下肯定就是直接让快递公司进行分了但是在计算机里面我们要把它解耦解的非常好的话我们就应该想清楚到底由谁来做。就单单拆电脑的情况快递公司是不会做的万一拆了以后到对端组装不起来就是快递公司的问题。所以快递公司不帮你拆这个东西你自己拆我的要求就是每个包裹5公斤拆完以后你给我就可以了你给我啥我发啥最后对方收到了能不能组装起来快递公司不关心也不负责。
同样的在网络报文里实际上分片或者把报文拆成多个的工作实际上就应该是网络层需要做的因为你把报文由一个变三个也要保证你拆出来的报文不是只有数据它也要在网络里传送的它也需要IP地址所以你在拆报文最后也是要给拆出来的报文在添加报头的(IP的报头)要不然我们的数据包也就没办法在网络里经过路由转发了所以必须得在网络层里对它拆必须得报文重新添加IP报头。当然如果你的报文是头部的本来就有报头其实就不用添加了但是多出来的报文必须添加报头。 这不能在链路层做就是因为链路层无法得知也不需要知道网络层的任何细节如果要在链路层分片的话就一定要保证链路层知道网络层的IP地址端口号然后给新分的报文添加IP报头这就不是链路层该做的所以分片工作必须得在网络层做。PS链路层也不是不能做但是一做耦合度就提升上来了就非常的不好。 谁来进行分片组装呢
所以我们在分片的时候必须得包含所有的分片细节如果你只负责分片一刀切分完之后直接添加报头什么信息都不做调整或者添加那么最终我们的整个报文也就没有任何的组装细节。没有任何组装细节的话对我们也就毫无意义。谁分片谁组装因为分片是在网络层里做的所以组装一定是对端的网络层IP协议进行组装。理由如下
分片之后所有报头信息的识别只有对端网络层需要有义务进行识别而且只有他能进行是识别。我们添加的这些分片的网络细节也只有网络层清楚。
什么是分片
其实就是把报文切成了多片。
如何进行分片
比如说网络层收到了一个报文它的大小就是1500字节现在要把这个1500字节交给链路层按照逻辑来讲是可以直接交付的但是不要忘了网络层还有20字节的报头所以网络层从传输层这里拿下来1500分数据要添加报头就需要有1520个字节交给链路层可是链路层只能传1500字节此时网络层它要向下交付就必须对1520这个报文进行分包1520包括了1500的有效载荷20字节的报头长度。现在要分包的话就必须把1520分成2个包。关键是分的两个包的大小是多少呢而且分的这两个包必须都得添加报头。 数据链路层最多就是1500而且这个1500是包含网络层的报头的意味着链路层传送的有效载荷最多是1480个字节。 所以我们将这1500字节至少拆成148020 将1480添加20字节的报头形成第一个1500的报文此时就可以直接通过链路层发送另外20字节也要添加20字节的报头形成40字节的报文然后交给链路层发所以这个时候才能进行向下进行数据转发。 实际上网络层在进行分片的时候它收到了传输层的数据假设收到的传输层的数据报文是X那么网络层就进行以下算法分片 最终我们的结论就是分片其实很简单如果网络层的数据太大那么我们在分片的时候只需要考虑将我们的数据分成多片但是一定要考虑每一片都要有报头如果今天网络层告诉你我要传送的数据字节数是1520是包含了所谓的报头的那么你一定要考虑它本身如果有网络层的报头的话你要把这个20作为第一个报文剩下的1500带入到上面的算法中进行分片然后在和原生的这个20报头一加然后交付给数据链路层就可以了。
eg: 分片 1.0 假设网络层里有个3420字节的报文且这个3420是包括网络层的报头的 2.0 假设网络层里有个3420字节的报文但是这个3420是不包括网络层的报头的 ps:进行分片的时候一定要知道交给链路层的报文有没有携带网络层的报头如果没有携带就直接按照链路层MTU的要求直接把报文拆成若干个然后再把每一个添加报头如果你本身就添加了报头我就需要把原生的这个报头作为待会拆分下的新报文需要添加的报头。 最终结论每个分出来的报文都必须要有报头。
组合问题 除此之外我们还要考虑组合的问题 比如传输层告诉网络层传3400个字节网络层收到的就是3400字节20字节(自己的报头)3420个字节3420要发送给链路层但是不符合规定就只能进行分片然后就变成了3个报文148020字节148020字节44020字节 此时到对端的链路层就直接发了3个报文对端的链路层交给网络层肯定也是3个报文。 请问这个分片的过程传输层知道吗怎们在技术层面保证传输层不知道呢
网络协议栈是解耦的当前层根本就不关心下面所有层的通信细节。所以传输层不知道。
所以底层一旦分片经过网络也分片传送到了对端链路层向上交付如果网络层不做任何处理网络层向上交付的也是3个报文那么传输层就知道了。所以当网络层收到这3个报文时需要进行组装组转好向对应的传输层交付也就是说只要我能组装好你曾经在对端传输层你给我网络层的是什么样子我在对端的网络层交给你传输层的也就是什么样子这样的话我在网络层的分片在网络层的组装你的传输层也就不需要知道了我也就相当于对传输层做了相关的隐藏。所以只要在网络层可以做好分片组装工作就能保证传输层是0感知的。
比如旧社会皇帝和财政大臣说要100万两白银财政大臣总不能和皇帝说有难处啥的所以只能答应过了一个月财政大臣就把100万两白银交给皇帝就可以了至于财政大臣在底下是各种搜刮民脂民膏就是他的事情了。
对我们来讲网络层到链路层以及网络层把数据报文交给传输层只要你把分片组装工作做好那么对于传输层就是透明的
这个分片的过程传输层需要知道吗
不需要知道
分片真的好吗
一旦分片之后万一有一个报文丢失了该怎么办呢
就比如上面的例子分片后变为3个报文而我就丢一个报文丢失一个报文的时候网络层就无法组装了此时的报文就变的残缺传输层给了网络层3400网络层也必须得给传输层3400所以万一有一个报文丢了就是组装失败组装失败以后整个报文全部丢弃也就意味着传输层交给网络层的3400个字节在对端传输层一个字节也收不到所以对应的就是传输层认为数据包丢包了丢包了以后就进行重传重传传输层在传入3400然后在重复刚才的过程如果还是在丢失的话就继续进行重传所以分片的缺点就是可能提高丢包的风险。
比如快递公司丢一个快递的概率是1%如果你把一台电脑由一个包裹分成3个包裹只要任何一个包裹丢了那么这台电脑你就用不了了所以你丢包的概率就几乎提升了3倍。相当于我们如果造成过多分片的话是会导致我们有丢包风险的。 可是你别忘了如果传输层是TCP还好它能进行重传可是如果是UDP(TCP/UDP底层都用的是IP)本来它就不保证可靠性你还在底层进行分片这个时候如果丢包了就只能组装失败然后这个报文就跟着丢了。 所以分片是可能提高我们丢包的风险的所以我们一般不建议分片所以IP分片不是大部分情况我们只有特殊情况才会分片。 如果我压根就不想分片了谁说了算
协议无非就是应用层传输层网络层和链路层如果今天压根就不想分片。链路层受硬件的约束这个MTU只能是1500链路层只是定制一个标准分不分片链路层说了不算网络层就是做执行的传输层发数据过来网络层添加上自己的报头然后交付给链路层网络层也没有办法所以网络层说了也不算再者如果网络层如果说了算还需要给自己的报文里添加分片和组装的字段吗它直接把报文控制的不要超过1500就行了所以只能是传输层说了算因为是传输层决定是什么时候发发多少出错了怎么办如何发的问题。所以之前我们讲TCP协议在进行网络传送的时候每一个报文我们都没有规定它的大小但实际上我们在网路协议设置的时候传输层在和对端通信的时候会和对面的传输层协商每次传输的单个报文的大小 所以传输层只要保证自己交给我们网络层的大小是1480个那么向下再走的时候就不会进行分片了。所以我们要让报文不分片是传输层说了算传输层确实不知道你分片了但是传输层可以帮助你还是不要让你在底层出现太多的分片。我们重点说的是TCP。
一般而言我们为了减少分片一般是要TCP控制自己的单个报文的大小的。
16位标识
IP报头里包含了3个重要的字段16位标识
16位标识我们收到了大量的IP报文如果大家没有任何分片那么每个报文的16位标识全部都是不一样的也就是每个IP报文都有自己的标识。如果没有分片不同报文标识符是不一样的如果分片标识符是一样的
比如我是一个接收方我将来可能会收到大量的IP报文如果这些报文中的标识符都不一样那么每一个报文都是一个个独立的报文。如果你将来分片分片后的报文每一片都要有报头就意味着每一片的标识符是一样的只有标识符是一样的我们才能把他们拿在一起。
13位片偏移 片偏移对应第一个报文就是0第二个报文就是1480意思就是说我这个分完的片偏移量在原始报文偏移量位1480的部分。第一个报文的偏移量第一个分片后的长度就是第二个报文的偏移量。 所以我们就可以把标识符相同的报文按照片偏移组合起来。 13位片偏移我的报文的有效载荷在原始报文的有效载荷中的偏移量。 16位标识位是把大家聚在一起13位片偏移就是把大家组合在一起。 分片后如何组装呢
只要根据偏移量升序排序就可以了。
我怎么知道有没有报文丢失了呢 丢包一共3种情况 整个报文的最开始丢了中间的部分丢了最后的部分丢了开始丢了我排序之后只要发现片偏移为0的报文没有就说明是头丢了 中间丢了一定是收到了头收到了尾排序之后我可以做一次检测从第一个报文的偏移量它自己分片的长度就应该是下一个报文的起始偏移量...经过这样的方式我们就可以有效甄别出中间有报文丢失的情况也就是说如果整个计算不连续了肯定是这个报文丢了。 所以前面丢了和中间丢了我们一点也不害怕我们完全可以通过片偏移确定出来。 尾部丢了我们最担心尾部丢了你怎么知道尾部的丢了呢
3位标志
我们不用担心我们有3位标志
3位标志1位保留1位禁止分片我很强硬我给链路层1800个字节可链路层只能传1500如果我设置了这个标志位那么我就不能分片我把这个1800字节的报文丢了都不能分片1位标识更多报文或者更多分片(这个标识位如果为1标识后面还有更多的分片如果为0标识后面没有分片了)。区分最后一个报文以及确认是否收全了所有的报文。只要把头和尾找到了中间有没有收全我们就可以通过片偏移判断了。
换言之我们收到的报文如果是第一个报文或者是中间报文它的更多分片位都是被置1的如果收到的是最后一个报文它的更多分片位就是被置0的。
接收端如何得知报文是独立的还是一个分片的
上面我们是已经假设是分片的所以我们可以知道如何填16位标识3位片偏移3位标志。可是对端主机收到的IP报文一定是混搭的既有分片报文又有正常报文所以我们要能够执行各种组合操作前提条件是接收方能判断对应的报文是有分片的或者是正常报文对于正常报文就直接向上交付了对于分片报文就进行组合排序。
我们通过13位片偏移和3位标志就可以确定报文是独立还是分片的
首先通过16位标识是完全分不出来的我们必须具体的判断出某一个报文是不是分片的。所以我们可以通过片偏移量如果你是独立报文你的片偏移量一定是0对于分片的第一个报文(片偏移量也是0)对于它我们就可以通过3位标志的更多分片标志位判断(一定是1)。
所以接收数据的一方检测3位标志的更多分片标志位是否为1以及检测13位片偏移是否不为0只要你的3位标志的更多分片标志位是1或者13位片偏移不为0那么你就是一个分片报文。然后在根据16位标识把他们放在一起然后组合排序就可以了。
第一个分片报文更多分片标志位是113位片偏移是0中间分片报文更多分片标志位是113位片偏移非0最后一个分片报文更多分片标志位是013位片偏移非0
对于正常报文
更多分片标志位是013位片偏移是0。
ip分片丢包了如何重传呢
只要在组装的时候识别到上面所说的任意一种情况ip就不将数据向上交付随着而来的就是TCP的重传。
因为 IP 层本身没有超时重传的机制——由更高层来负责超时和重传 TCP 有超时和重传机制但 UDP 没有。一些 UDP 应用程序本身也执行超时和重传。当来自 TCP 报文段的某一片丢失后TCP 在超时后重发整个 TCP 报文段该报文段对应于一份 IP 数据报。没有办法只重传数据报中的一个数据片。事实上如果对数据分片的是中间路由器而不是起始端系统那么起始端系统就不无知道数据报是如何被分片的因为这个原因经常要避免分片。
网段划分
IP地址分为两个部分, 网络号和主机号 网络号: 保证相互连接的两个网段具有不同的标识; 主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号; eg:下图这两个大方框对应的就是两个网段如果你不理解网段你就可以把理解成这是两个不同的局域网这两个局域网之间用路由器连接起来其中这两个个局域网所对应的网络标识在同一个网段内所有主机的网络标识都是一样的第一个网段内就叫192.168.128另一个网段的网络标识是192.168.144。大家在不同网段中网络号是完全不一样的在同一个网段内网络号是一样的这就是网络号的概念。在同一个局域网内大家的主机号是不一样的如图都是10和11号。 局域网双方是通过路由器连接起来的路由器会记住192.168.128192.168.144这样的网络标识因为路由器本身是横跨至少两个子网或者网络的所以路由器在上面的这个子网看来也必须配有IP地址。一般而言你的网段内的第一号主机通常是给路由器的在第一个网络里的标识是182.168.128.1在第二个网络里的标识是192.168.144.1。路由器是负责跨网络传送的所以路由器必须至少有两套网络接口(说人话就是必须得配两张网卡每张网卡里各种配一个ip) 路由器必须横跨至少两个网络要不然它就没办法进行网络转发。所以有路由器的存在我们就可以将数据从一台主机转发至另外一台主机。
比如第二个网段内的主机发出一条数据目的IP写上192.168.128当它把数据发出去的时候它立马就可以判定这个数据不是给我当前局域网内的主机发送的所以我就把他扔给了路由器路由器因为横跨了两个网络所以它对两个网络都认识它内部查路由表发现你要去的目标网络就是192.168.128主机号比如说是10号所以路由器就可以把报文转发给10号了。
换言之我们可以通过路由器桥接两个不同的网络路由器在每一个网络内部都必须认为它也是这个网段内的一个主机。 IP地址是32位的所谓的网络号或者主机号说白了就是把我们对应的32个比特位进行比特位的划分前面的若干比特位标识网络号后面的标识主机号。不同的子网就是把网络号相同的主机放在一起如果你在子网当中新增一台主机那么这台主机的网络号和这个子网的网络号是一样的但是主机号不能和子网中的其他主机重复。 比如你在你家各种智能设备连接的网络前面的若干位是一样的后面的数字不一样因为大家是属于同一个子网。
eg:博主手机平板电脑都连接同一个WiFi它们ip地址的前16位就都是一样的 通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同.
如何分配IP地址呢 比如今天我们在一个大局域网里因为我们是同一个局域网所以网络序号都是一样的然后只要保证主机号是不一样的就可以了。 IP地址是需要被回收的因为IP地址就是一个数字我们有32位的IP地址意味着全球的IP地址最多也就是2^32个随着时代的发展入网设备变的越来越多早期入网设备就是一些台式机服务器现在变成了笔记本手机各种智能家电...其中IP地址既然是有限的那么IP地址就是一种资源所以这种资源一旦被分配出去当你不想用的时候一定要想办法回收它。 在局域网中分配IP的两种方式
一种就是手动分配比如你自己想上网你给我一说我就在你的笔记本上给你录一个IP然后录好IP之后我在我的网络的服务器中分配IP的节点当中把你的IP地址登记上手动管理。但是手动管理早就被淘汰了这种管理方式非常恶心比如说网络中新增了一个节点那么你还得手动的把这个节点去配置一下然后如果网络中有一个节点掉线了或者不要IP了那么你还得手动回收它。只要人参与效率肯定就低。还有一种技术叫做DHCP能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便。一般的路由器都带有DHCP功能. 因此路由器也可以看做一个DHCP服务器。ps:所以认为路由器只是进行路由器转发的网络世界中的一大误解就是大家认为路由器只能进行路由转发好多教材都说路由器只是工作在网络层的(这是因为这些教材已经老了)现在的路由器相当先进甚至都能跑HTTP所以现在的路由器已经俨然是一台独立的计算机了只不过这个计算机不是给你用的它没有显示器没有键盘它的输入输出就是网络所以路由器的功能是非常强大的路由器内部都有这DHCP动态IP地址分配的功能。 比如在同一个局域网内每台主机都是需要IP的我们以无线WiFi为例当你进入到某个场所的时候你想联网默认情况下你用的是你手机的流量例如4G5G。你到了你朋友家你先连接诶他家的WiFi你就要询问对应的WiFi和WiFi密码所以当你连接WiFi的时候本质是你的手机在访问路由器路由器对你这个人的合法性进行认证(当然也可以不设置密码一般我们是有密码的)认证完了你就任务你连上了实际上认证完后路由器的工作并没有做完手机的工作也没做完。路由器会在自己历史上已经分配的IP当中选择一个没有被别人用过的IP然后返回给你你的手机拿到之后就充当了你手机的ip然后你就可以去上网了。因为所有的人想上我的网都必须得连接我的路由器所以也就意味着整个局域网中所有ip地址的分配和回收都是由路由器完成的路由器给每一台设备分配ip的过程就叫做DHCP的过程。(这里的ip就是局域网中的ip)关于网络划分和建设 类比生活中的例子展开学校里每位人都是有学号的。学号都是有规律的。今天我们可以简化下模型把学校专业当初一个整体班级个人当成一个整体。实际上我们在学校里面会建各种群属于同一个学院专业的人可能会在一起。比如软件的群计科的群经管的群...所以我现在就相当于把我们学校以两个维度的方式以学院专业作为一个整体班级个人作为一个整体然后就划分了一个叫做网络号和主机号。网络号就相当于学院专业只要是学院专业相同的学生就在同一个群里。主机号就相当于班级个人。每个专业群里都有一个学生会主席每个专业的学生会主席也都拉一个群。 目前就是我们所有的不同专业的同学组成不同的群这就是一个个局域网。每一个专业的学生会主席也组了个群这些个专业学生会主席就可以称之为入网的路由器所有的这些路由器也共同构成了另外一个局域网。 每一名相同学院专业的同学是在一个群里面的每一个群就构成一个局域网每一个学院专业都有自己的学生会主席这些学生会主席在全校的学生会主席中自己建了个群所以他们自组网络了。 假设我是计算机专业1班2号的学生假设我今天捡到了一张学生卡 我看到了他的学号信息假设我现在要归还给他我难道是逮住一个人就去问下这个人是不是这个学生卡的主人如果不是再接着找下一个人吗 答案肯定不是。 查找的本质其实就是排除的过程当你在一个一个轮询去遍历的时候你一次排除的只有一个如果全校有2万人等你找到就要猴年马月了。 所以我的做法就是搞了这样一个信息信息内容是该学生的学号这个学生的学生卡丢了并附上了我的联系方式然后我就把这个消息发到了我自己的专业群里面并且了学生会主席通过学号辨认出这个学生不是我这个专业的所以学生会主席就把这个消息发到了学生会主席的群里面并且校学生会主席。因为校学生会主席和大家都熟悉各个专业的学生会主席只认识自己的网络但是校学生会主席就应该记录下各个学生会主席所负责的子网的网络号所以校学生会主席认识校园所有的学院和专业校学生会主席收到一个报文一判断判断出这个学号是经管学院的然后校学生会主席就了经管学院的学生会主席然后经管学院的学生会主席确认了一下发现确实是自己院的然后经管学院的学生会主席就把这个报文收到了然后发现这个学生就是田七借接着就在经管群里田七田七就看见消息发现学生卡确实丢了然后就给我打电话。 此时我们就通过一个群内转发的方式从一个局域网经过路由器转发到大的网络转发环境当中(其实就是公网) 然后在大的公网当中经过一系列转发到达田七所在的经管学院的入口路由器(经管学院的学生会主席)然后在把信息转给田七田七就收到了这个信息。
这次就完成了一次查找的过程其实是完成了一次数据转发的过程。 我这次查找在路上的时候(我自己学院的学生会主席校学生会主席经管学院的学生会主席) 这些人只关心学号的前半部分(学院专业信息)比如计科学院的学生会主席只看这个学号前半部分识别到不是我们学院的就转发到学生会主席的群里校学生会主席也只关心学号前半部分发现要转个经管学院的学生会主席经管学院的学生会主席也只关心学号前半部分发现确实是自己学院的然后把信息发到经管群。 当到达目标群(到了经管群)就只关心这个学号的后半部分(学生的班级及号码信息)。 这个学号的前半部分就叫做网络号学号的后半部分就叫做主机号。 查找的时候在路上的时候 通过划分不同的群来进行查找的。本质就是一次可以排除1个或者多个群。刚刚我们的这种行为将所有的学生进行编址划分成两部分(左部分是学院专业右部分是班级个人)我们称之为网络号和主机号另外我们把所有的网络号还要进行不同的编址这就叫做网络划分。
网络划分本质 所以网络划分本质就是为了提高查找效率减少查找的难度便于组网 所以我们对IP地址进行划分就是网段划分的概念不同的编号就是不同的网段划分成不同的网段能提高效率本质就是它增加了排除的概率一次就可以排除大部分人。 根据上面的例子我们发现查找的时候在路上的时候我们只关心目标网络到了目标网络的时候我们在根据目标主机找到对应的主机。所以路上找的时候全都是根据目标网络去查找的我们可以对二进制序列做划分然后就可以建立各种各样的群把相同的学院专业的人放在一起。 刚刚划分的是一所学校如果把整个地球看做成学校的话实际上网段划分是比较复杂的与运营商组建网络有关系我们可以把全球的网络根据IP地址把IP的网段号划分给每个国家然后每个国家里面可以用递归的思路进一步划分。 当然这里只是描述下我们其实是可以把所有的这些IP地址在全球内划分完的。我们把整个地球想象成学校的话中国就是1号大群我们也有很多国际路由器这些国际路由器之间组建成大群组建成的大群在国际上就可以进行转发。 以上只是一种草案国际网段划分组织已经帮助我们划分好了。 分类划分法
过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示,这种划分网络IP地址的方案就叫做分类划分法。其中把ip编号划分到全球之后重点是为了让各个国家的运营商要进行组网的。分类划分法 拿出第一个比特位我们叫做A类剩下的我们叫做其他也就是第一个比特位为0就是A类剩下的第一个比特位为1就是其他类。所以我们的网络就是A类和其他类。对于B类从第二个比特位开始如果为0就都属于B类剩下的就是其他对于C类从第三个比特位开始如果为0就属于C类剩下的就是其他依次类推除此之外每一类IP还有网络号和主机号。比如中国拿到了A类网络我们并不是把全国人民建一个大群否则你发个消息14亿人民都看的到这肯定是不行的所以我们拿到A类网络之后我们进一步可以根据这里的网络号把全国在划分成若干个省在根据24位主机号在进行切分最后落实到一个很小的区域后大家就都有了一个网络号了。所以我们用ABCDE把网络整体划分成若干类然后有的类还有网络号和主机号供我们在申请到的这一大类的网络当中在进行细分。为什么分类要分ABCDE这样的类别呢
因为每一个国家的大小人口是不一样的比如中国就应该拿A类日本拿一个D类C类就可以了它并不需要那么多。比如我们国家拿了A类网络号设置成1印度也拿A类开头也为0网络号给他分2....这只是个例子实际上这个只和运营商各方面有关系。对于日本法国波兰就拿B类的然后把网络号再给这些国家分一批实际上一个国家可以申请多个就好比B类网络号就可申请多个一个不够就两个两个不够就三个...eg:中国把A类的网络号的1,2,3号都占了。所以我们就可以很粗粒度的把IP地址分向全球让所有人都拿到。所以就可以知道这些IP范围A类 0.0.0.0到127.255.255.255 B类 128.0.0.0到191.255.255.255 C类 192.0.0.0到223.255.255.255 D类 224.0.0.0到239.255.255.255 E类 240.0.0.0到247.255.255.255为什么ip划分是这种分类划分法呢 因为全世界的国家大小是不一样的每个国家需要对应的IP地址的数量也是不一样的如果是平均划分方案就是不合理的小的国家用不完大的过节不够用。所以分类划分可以适配不同国家的体量让不同的国家可以拿到不同区域的网络。 再比如我们国家拿了一个A类的然后第一个标志位必须是0因为是A类的网络号是1我们把主机号就使用20位腾出4个比特位表示是哪个省的....如果你愿意还可以在细分PS这里说的ip都是公网ip。所以我们可以通过以地域的方式把ip地址也划分成一个个的大群就好比全球是个大群全球所有的国家对应的代表人物就参与我们全球的网络就好比全球就是我们的学校各个国家的代表任务就相当于专业学生会主席他们在全球中自建一个路由器级别的网络接下来把我们国家又可以当成一个学校按照省市区划分。实际上IP地址是可以按照地域的方式划分好的。所以近些年我们在一些社交APP评论的时候是可以看到评论人的地区。这是因为这些软件可以根据你的ip地址来追溯你是属于哪里的ip然后就知道你是谁了。 CIDR
随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址, 导致B类地址很快就分配完了, 而A类却浪费了大量地址;比如日本申请B类连续申请了10个B类的网络个数。只要保证大家的网络号不一样就可以。例如, 申请了一个B类地址, 理论上一个子网内能允许6万5千多个主机. A类地址的子网内的主机数更多. 然而实际网络架设中, 不会存在一个子网内有这么多的情况. 因此大量的IP地址都被浪费掉了. 针对这种分类划分法浪费ip的情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing): 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号; 子网掩码也是一个32位的正整数. 通常用一串 0 来结尾; 将IP地址和子网掩码进行 按位与 操作, 得到的结果就是网络号; 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;eg: 所谓的子网掩码就是一串全1和全0的组合我们可以用全1和全0的方式通过设置子网掩码当中右半部分全0的个数来限制一个局域网内主机的个数。比如子网掩码有半部分有10个0就代表可以用的主机数是2^10个。 eg: 划分子网1 划分子网2 可见,IP地址与子网掩码做与运算可以得到网络号, 主机号从全0到全1就是子网的地址范围; IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68, 子网掩码的高24位是1,也就是255.255.255.0。 所以划分子网的方案有两种
第一步是先粗力度的把全球的网络按照分类划分法分好第二步是在架设子网的时候给每台路由器都设置上子网掩码这样就可以通过限制子网掩码的位数来调整我对一个网络当中能够允许构建的主机数进行约束进而不造成ip的浪费。实际上有一个报文带着目的ip我们是拿着目的ip和子网掩码进行按位与得到网络号这个网络号一得到就根据网络号进行路由转发将报文转发到特定的区域当中。
所有的网络在全球内每一台机器的ip不一样这个ip我们叫做公网ip其中我们只要保证网络号一样的放在一起就可以建各种群一旦建好群了要对外入网 就必须得要路由器接通公网路由器也是主机我们就可以把所有的路由器组建各种的网络情况只要大家相同的网络号在同一个主机上我们就可以使用网络号在全国范围内进行路由查找这个事情是可以做到的就是由中国移动联通电信这样的运营商做的。
特殊的IP地址
将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;
例如把172.20.0.0/16用二进制表示如下
10101100.00010100.00000000.00000000 二进制
将这个地址的主机部分全部改为0则形成网络号
10101100.00010100.00000000.00000000 二进制
再将这个地址用十进制表示则为172.20.0.0。
将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包;
例如把172.20.0.0/16用二进制表示如下
10101100.00010100.00000000.00000000 二进制
将这个地址的主机部分全部改为1则形成广播地址
10101100.00010100.11111111.11111111 二进制
再将这个地址用十进制表示则为172.20.255.255。
127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
IP地址的数量限制
我们知道, IP地址(IPv4)是一个4字节32位的正整数. 那么一共只有2的32次方个IP地址, 大概是43亿左右. 而TCP/IP协议规定, 每个主机都需要有一个IP地址. 这意味着, 一共只有43亿台主机能接入网络么? 实际上, 由于一些特殊的IP地址的存在, 数量远不足43亿; 另外IP地址并非是按照主机台数来配置的, 而是每一个网卡都需要配置一个或多个IP地址. CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率, 减少了浪费, 但是IP地址的绝对上限并没有增加), 仍然不是很够用. 这时候有三种方式来解决: 动态分配IP地址: 只给接入网络的设备分配IP地址. 因此同一个MAC地址的设备, 每次接入互联网中, 得到的IP地址不一定是相同的; NAT技术(后面会重点介绍); IPv6: IPv6并不是IPv4的简单升级版. 这是互不相干的两个协议, 彼此并不兼容; IPv6用16字节128位来表示一个IP地址; 但是目前IPv6还没有普及;
私有IP地址和公网IP地址
以上我们谈论的所有内容都是公网IP。
实际上公网IP一共才42亿多入网的主机太多太多就比如我们的手机电脑连接上WiFi用的是公网IP吗实际上用的不是公网ip。 eg:我们是有云服务器的如果拿笔记本去ping云服务器是能联通的但是反过来是不行的。 这是因为公网ip不够了所有公网ip是不会给用户去用的所有我们必须得考虑一下怎么让ip地址能够让更多人接入网络。所以我们就有了组建局域网和划分ip地址的另外一个角度。 如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上(也就是公网上),理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址10.*,前8位是网络号,共16,777,216个地址 172.16.到172.31.,前12位是网络号,共1,048,576个地址 192.168.*,前16位是网络号,共65,536个地址包含在这个范围中的, 都成为私有IP, 其余的则称为全局IP(或公网IP)
私有IP不会出现在公网当中也不能出现在公网当中也就是说在公网里面跑的所有报文的目的源ip绝对不是私有ip。 eg:笔记本的ip就是私有ip linux下主机的ip也是私网ip 这个ip是内网ip也叫作腾讯内部组建局域网时所用的ip你实际上想让外网访问你你必须得用自己的公网ip地址。 全世界有很多的私网ip这些ip够吗
公网ip在整个公网世界是不能重复的私有ip在自己私有网络内部也是不能重复的比如你家里面你的手机的ip和你爸手机的ip绝对不一样只要你连接的是同一个网但是我家里的网和你家里的网和张三家里的网络都叫做局域网或者路由器给我们构建的子网此时我们其实是可以使用同样的ip的比如我在我家里的一台主机的ip是172.29.131.179你有可能在你家里也有个ip也叫作172.29.131.179。这就意味着私网ip可以在不同的子网中重复出现。所以这样的话就解决了公网ip可以给公网去使用包括给运营商构建我们自己对应的入网设备路由器配置的路由设备所有想接入公网的人他只能使用私有ip而要使用私有ip就必须得先入网入网的时候就必须得有路由器给你构建出一个私有ip所有全世界人类大家在自己的局域网里面用的全部都叫做私有ip只要大家都用的是私有ip的话那么你的数据发出请求以及在公网中跑的时候是由路由器帮你请求的。所以全世界人类在接入网络时不用公有ip接公网而是直接使用私有ip接路由器的方式来进行接入网络的。
对于运营商的理解 运营商其中像移动联通电信我们刚刚说的子网划分子网掩码这些网络的划分过程是由国家内部的运营商做的。人家在哪构建的基站如何构建的局域网及局域网之间如何划分的你都不清楚。 所以子网划分就弱化一下。对我们而言所有用户上网都用的是私有ip 你自己天天用看抖音玩吃鸡游戏使用各种APP...不管你是用流量也好还是用WiFi也罢你最终交钱的时候都是交给了运营商(移动联通电信)。这是为什么呢你为什么不把钱交给这些APP呢
根本原因在于这些APP的公司叫做互联网公司互联网公司实际上不是创造了一个时代而是时代创造之下的产物。
为什么中国有这么多的互联网公司呢
比如非洲这样的国家就没有像抖音这样的APP。2000后这些互联网公司才进入人们的视角互联网公司只能是顺应时代的人所以这一切都是因为基础设施。你家里的网包括你的数据走在了公网中包括你的数据转发到提供方对应的服务器里面。所以你一直走的都是运营商曾经搭建好的基础网络。从生活角度如果你家里想开网络的话你爸你妈必须得给移动联通电信其中的一家打个电话然后就有专门的工作人员上门把光纤引入到你家里面然后给你安装强制解调器(也就是俗称的猫)路由器然后把WiFi给你全部弄好然后你才可以上网而且你家里交网费全部都是把钱交给了移动联通电信。是因为三大运营商是国家的基础设施建设的缔造者也就是说你在门口所看到的各种基站曾经铺设的各种光纤还有各种企业级的交换价路由器等各种各样的基础设施运营商全部给你搭建好了。硬件存在之后运营商还要和其他软件公司去合作比如华为去定制出自己的1G2G3G4G5G这样的通信标准然后在硬件层面上保证你的数据能够以光电信号的形式从A端通信到B端...这些工作可不是互联网公司做的只有运营商会做这些事情。
为什么互联网公司不做这些事情呢
1.最简单的一点就是互联网公司是私企三大运营商是国企。
2.互联网公司的钱在三大运营商看来就是毛毛雨虽然互联网公司也非常转钱但是如果互联网公司在基础设施方面进行投入的话它也扛不住。
3.互联网公司不愿意做这些事情也不会愿意做这些事情因为互联网公司都是资本催生下来的产物如果一件事情你投入之后可能20年之后才能看到回报这些互联网公司是不会做的回报周期太长了。在比如这些互联网公司曾经都有很多的投资公司投资公司最重要的就是把钱给你短期之内就要看到利润因为投资公司没有耐心等你20年在拿到利润。投资公司就是要短期内的利润然后在拿着这些利润去投资下一家的公司投资公司快速的发展就要快速的滚雪球就要要求被投资的公司快速的赚钱。所以往往背后挂靠这些资本的公司特别急功近利就是喜欢赚短钱长期的钱虽然也能赚但是它不想赚。万一在这个等待的时间内你这个被投资的公司垮了就得不偿失了风险非常大。所以只有少数的公司在资本的催生下是成功的大部分公司在资本的催生下都倒闭了。
互联网公司不想做基础设施投入就是因为前期的投入成本太高一次就把公司的几年利润投进去投入之后长时间得不到收益而且还得慢慢建设这是互联网公司不愿意看到的。而且一旦有一家公司愿意做技术创新愿意把公司全部的利润投入到基础研发中推动整个行业的发展那么这个公司是非常非常有魄力的公司而且是需要有强力的领导人的最具有典型代表的就是两家公司华为与联想。大家鄙夷联想赞美华为就是大家觉得这些公司赚了社会这么多钱就应该去投入去促进社会进步促进行业的进步可往往现实和理想总是事与愿违的你没办法去要求人家人家或多或少是私企。
运营商愿意去搭建基础设施吗
所以大家都不愿意做这样的事情当然国家不让你去碰也是有可能的这种活只有三大运营商去干他们愿意去干嘛
一方面他们就是干这个事情的从赚钱角度来看他们也不愿意干以前发短信打电话也得交话费那为什么还要投入基础设施建设给你建设3G4G网络呢
运营商的动力也还好但是因为国家发展的需要所以是要大家不断进行基础设施的创新的。而且我们也都知道我们的网络技术其实是跟着别人的步伐成长起来的你不进步别人也在进步所以不管是对外部的压力还是内部的需求我们都是要推动整个事情的。所以在国家政策推动下三大运营商就大面积的铺设基础设施网络建基站架设各种光纤...
运营商架设好的路线就类似于你以前想要去县城你进不去因为路太差了现在有人给你把路铺好了那么你这个人就可以去县城了因为你可以去县城里那么你周围的人也能都去县城了所以去县城的人也就多了那么那些小商小贩就可以聚合起来去做人们的生意了小商小贩把人们的生意做起来了然后就慢慢出现了一些大点的饭店最后生意越做越大于是小商小贩就喊“是我创造了这个县城的繁荣是我铸造了这个时代” 现在看来这就是笑话。
互联网公司只是时代之下的产物如果曾经没有人修好路那么就就不能能有人去县城所以基础设施就是一切繁荣的前提就和你账户余额一样你后面有再多的0也没有意义你必须得在前面带一个1。
所以前期投入这些事情的人是最值得鼓励的而且前期如此投入还是有很大的风险的就比如万一你把路修好了但是还是没有人愿意去县城县城就繁荣不起来路上的人越少你这些运营商的投入就没法回收了不像小商小贩前期就是花了几百块推这个车车就到了县城大不了没人了就不干了损失也就是几百几千块钱可是对于曾经把路修好的人损失的就不是这一点半点了。
这些基础设施架设好了要不要回收成本呢
当然需要就事论事这些基础设施没有运营商不行至于后续的故事运营商内部管理混乱乱收费现象...好的表扬坏的使劲喷。
对我们来讲自己上网的时候插的是运营商的电话卡用的是别人的4G5G网络家里上网的时候交网费是交给运营商的因为基础设施是人家干的就应该给人家交钱。就好比当你上高速的时候你得交过路费因为高速公路是人家修的基础设施是人家建设的人家为了回收这个成本必须得收费这是最简单最直接的回收资金的方案。人家承担相应的风险高技术即使要回收成本甚至要获取一定的利润也是值得鼓励的要不然谁还愿意干这些事情呢。
至于你打游戏充钱这就是你和互联网公司的事情就好比你到县城了与餐馆老板勾心斗角你把钱交给餐馆老板点了很多菜这就是你与互联网公司的事情至于这个菜是怎么点的就与互联网公司的商业模式是有关系的比如你吃饭不要钱但是你得看10分钟广告你吃饭交钱你可以免费吃饭但是你必须得去某一个地方做一件事情...互联网公司是互联网公司的玩法但是基础设施投入的运营商的玩法就简单粗暴我给你把路铺好你给我交钱就这么简单。
我可以上网的时候不给运营商交钱就想直接访问别人的服务器可能吗
完全不可能就好比我就不想走国道不想走高速凡是政府修的一切路我都不想走我就想走羊肠小道从北京一直干到云南这完全不可能。因为你手机的光电信号是不可能凭空发送到别人的服务器上的另外你手机发送的这种视频信号其实是经过各种对应的基础设施转化的服务器是不认识这些东西的而且基础设施连都没连你怎么访问服务器呢所以你是绝对不可能绕过运营商的你的所有的请求都必须通过运营商给你架设的基础网络到达互联网公司对应的服务器。你绝对绕不开运营商。互联网公司同样也是三大运营商的客户互联网公司要建机房也必须得用运营商的基础设施。所以网络背后的大佬是这些运营商因为小白属于运营商的客户大的互联网公司也是运营商的客户你可能拉个几百兆的网络互联网公司要拉的就是几百个G的光纤到自己的机房互联网公司也是客户你上网要交钱这些互联网公司同样也是需要交钱的。
为什你欠了话费不能给其他人打通电话但是你确能给运营商打通电话
实际上你的欠费欠的就是运营商的费用你又没有欠互联网公司的费凭什么不让你使用网络(滑稽)因为你用的是人家互联网公司的资源所以当你一旦欠费是运营商把你的网络掐了你的电话号码就是你的账号和你电话号码绑定的信息包括费用信息都是运营商数据库里面的一张表人家知道你欠费了运营商就不让你上网了说白了就是运营商不在把你发过去的报文做转发了不给你转到互联网公司当中那么此时你就上不了网了。但实际上你的消息其实依旧是发给了运营商的。运营商再怎么傻也得把缴费的通道给用户打通所以一般你是可以给10086客服打通的。
实际生活中我们发现只要欠费了你自己是交不了的你必须得让你朋友交或者连上WiFi缴费为什么移动不把这个缴费的接口放开呢
猜测
1.可能怕被人们吐槽欠费了什么都打不开只有10086能打通缴费能打通这不就明摆着要钱吗。移动就吃准了你一定会想办法缴费的反正是你主动交钱的而不是移动问你要钱的
2.缴费也有可能和银行系统有关系比如你交钱的时候中国移动也有自己的移动账号银行也属于基础设施的客户如果你交钱交给银行的话还是要访问外网这可能有问题因为你转钱的话不是把钱转给了中国移动而是把钱转给了中国移动所在的银行账号银行也是运营商的客户作用和互联网公司一样你把钱交给运营商的银行账号可能也要走外网这样做容易出问题你欠费了只能访问银行这样也不太好所以移动就没放开。
当然从技术角度来讲运营商想实现欠费情况下缴费完全是可以的只不过人家不愿意做罢了。
回顾之前的子网划分 运营商帮助我们组建了各种各样的子网好比上述群与群转发消息的例子计科学院和经管学院不是一个群但是就是能把消息从计科群转发到经管群我们两个群是没有直接相连的但是我们有对外的路由器我们可以把所有的路由器全部集中连接起来这样我们就可以组成新的网络相当于学生会主席之间的路由器可以用来数据包转发。如果你把全球想象成一所学校我们就可以把各个国家想象成一个群一旦建立好这个划分之后进一步把一个国家在想象成一个学校在一个国家里面又划分成各种省省之间也可以在进一步的进行子网划分一般我们常用的就是子网掩码。省划分成市市划分成区总之我们一定有方法把全球的地区都覆盖上对应的网络这是可以做到的。 我们经过这样的不断向下划分后各个地区的网络是有它自己的一部分区域覆盖的比如你家附近就有一个专门的运营商小店帮助你联网当客户想上网的时候就把网络拉倒客户的家里面当我们的这些运营商把网线拉倒你家里的时候背靠的就是整个网络的基础设施 实际上不要把运营商认为是一个帮助我们转发数据的运营商也有自己配置子网的一些方式其中也有自己各种企业级的交换价或者路由器。
比如 ip为122.77.241.3就是给我们提供服务的服务器(比如说是抖音的服务器)上图中的电脑设备就是我们用户。我们每一个人要上网的时候首先给移动打电话移动就派一名工作人员过来给你拉好网线安装强制解调器安装家用路由器。路由器的密码是有两套的第一套是给用户的就是你家的WIFI密码第二个就是这个路由器内部需要设置一下你的缴费账号通过这个账号信息去认证你。
路由器是可以用来组建局域网的不光是你的家用路由器运营商的大型路由器也是可以组建的。运营商路由器之间构建的网络就是公网。这个运营商路由器最大的意义管理它旗下的路由器当用户请求的时候可以把你的请求给转发出去。
eg:手机是可以上网的你可以把你的手机热点打开然后让你周围的同学连接上你的热点去进行上网。把你的手机热点打开就是把你的手机当成一部路由器组建了一个局域网让你的朋友去上网上网的时候你的朋友用你的热点就是把数据发到你的手机上通过你手机的路由功能再把数据发出去这就是一个构建子网的过程。所以路由器只要能不断的去构建子网网站在基础设施建设就可以把子网不断的去细分。
一般的家用路由器或者运营商路由器都会配置上两个完全不同的ip因为一个路由器要转发报文就必须得横跨至少两个网络
路由器对内的ip叫做子网ip也叫LAN口ip对外的ip就叫做WAN口ip
运营商路由器的WAN口ip很明显就是公网ip了我们就可以通过它把消息转发到其他网络。换句话说这里的运营商路由器可以让用户把数据通过公网转发到服务器。实际上运营商再牛也不可能把基础设施架设到美国去。其实国家和国家这个广域网之间我们也是要通过一些国际的线路去互相联通的。
所以对我们来讲企业就可以将自己的信息接入到公网当中用户通过自己的私有ip也能接入到公网当中此时用户就可以直接去上网了。当然企业接入公网的时候很多的主机甚至都是公网ip。
总结
1.所有的用户对应的信息是在家用路由器当中以局域网的形式接入网络的。
2.每个路由器都有自己的LAN口(子网ip)和自己的WAN口。
3.路由器是可以构建子网的。
4.当运营商把基础设施构建好后互联网公司要接入就可以直接把自己的若干台机器接入到公网之中背靠的也是自己内部的机房只有少量机器是可以入公网的。将来你的客户请求都是要通过这些基础设施转发的。
客户的一个请求是如何转发给另外一个客户的呢
比如我想搜索我怎么把我的请求转发给百度呢
我拿我的192.168.1.201经过报文转发交给家用路由器这台家用路由器可以看到我的目的ip一定填写的是百度的公网ip家用路由器在做路由查找的时候发现你不想再局域网内转发这个目的ip和家用路由器的子网掩码做按位与发现目的ip的网络和家用路由器的局域网不一样就转发出给运营商路由器运营商路由器又帮助我们在公网中找到百度的公网ip。此时百度就收到了源ip是192.168.1.201目的ip是122.77.241.3这样的一个报文百度收到了就会根据你的要求构建一个响应但是构建响应的时候就出现问题了。因为百度构建响应的ip就是192.168.1.201可是这个ip是私网ip全网中这个ip是可以重复的百度也就无法把这个报文给你响应回来就是因为私网ip不具有唯一性。
这个时候运营商就出现了当你请求的时候你请求的目的ip一定是122.77.241.3你的源ip是 192.168.1.201当你把你的请求发送到对应的家用路由器的时候此时家用路由器会做一个工作会把你的源ip替换成家用路由器的WAN口ip就是10.1.1.2(当然也有可能把你的端口号也替换调)当家用路由器转发给运营商路由器的时候就如同这个报文是家用路由器产生的一般。当交给运营商路由器的时候运营商在把这个报文的源ip替换成运营商路由器的WAN口ip122.77.241.4替换完毕之后此时到达公网的这个报文的源ip就是公网ip了然后百度收到这样的请求就认为是这个运营商路由器发来的所以百度收到请求后构建响应然后就把响应报文返回给运营商路由器。
所以我们自己的请求在对外发送的时候我们的源ip地址可能一直在被中间路由器替换这样的技术我们称之为NAT技术。
那么现在构建响应回来如何把数据准确的响应给用户呢
稍后回答。
为什么私有ip不能出现在公网上
路由器既能构建子网又能分配ip还能做地址转化。这也就是为什么这些私有ip不能出现在公网上不是不能而是不可能因为你想要上网就必须得走运营商运营商所有的路由器包括你自己的家用路由器都得给你做地址转化所有凡是公网上的报文是不可能出现私有ip的。
我能不能直接把消息转发给我的朋友呢 我想把我的数据直接通过运营商路由器去转发而不经过公网这能做到吗
从技术角度是可以做到的但是常规情况下这种方式是不可能的因为我们两个的ip地址都一样你想要把数据通过家用家用路由器转发给朋友是不可能的虽然路由器是会给我们做ip地址转化的运营商路由器也确实可以把报文通过你家的路由器转发到你朋友家的路由器上但难点就是怎么让家用路由器把这个请求交给你的朋友。
大部分情况下不同子网的两个人想直接通信的难度比较大一些不是不可能也是有方法的从技术角度实现也还行关键是我们两个要直接通信最好还是要经过公网去通信。
正常情况下你要和我通信说白了就是你的软件和我的软件通信所以对我们来讲大部分情况下的工作方式就是你自己写个客户端把你的数据放在云服务器另外一个客户端也是连上云服务器从云服务器上拿数据所以我们两个要通信实际上是要通过云服务器做数据交换的。
有些技术是不需要通过云服务器做交换的比如有些下载服务eg:快播 (时代的眼泪)包括很多的软件如果进行下载走公网太慢也可能会做一些发现技术。
总之一个局域网不经过公网到另一个局域网这种情况从技术理论上是可以的。
浅谈墙
比如你欠费了运营商就不让你上公网了这就意味着运营商是可以拦截你的请求的我欠费只是一个条件就比如如果我没欠费我想做其他事情运营商也是有可能拦截我们的我们经常说我们国家的网络是有墙的我们访问外网要翻墙。你自己的一些请求不太合法的话运营商是有能力拦截你的所以我们经常说的墙是三大运营商手拉手构建起来的说白了就是当你的一个请求当中涵盖了非法的请求时运营商内部也会做各种甄别换句话说不要认为你天天访问某些网站的时候别人是不知道的运营商一定要对你的数据做检测的它要知道你访问的网址是不是合法的是国内的还是国外的。所以运营商对你的请求做检测如果检测到你的请求是非法的那么运营商直接就把你的报文在自己的基础设施这一层直接给你丢弃掉一旦把你的请求丢弃掉就出现了你访问的网络不可求所以墙就是在运营商基础设施里面相当于三大运营商给我们构建起来的信息屏障。对我们来讲运营商构建起来的信息长城拦住了我不让我去访问外网同样的拦住你的同时也拦住了别人外网想访问我们也必须得想办法穿过运营商的基础设施。
运营商的拦截策略有很多就比如你想访问谷歌是访问不了的你的请求的时候首先要拿到谷歌的域名人家解析不了这个域名就访问不了即便你解析了一旦发现这个ip是谷歌的人家也不让你访问。所以运营商可以通过你访问的网址ip信息去拦截你识别到你文本信息内包含国外的网址话就直接把你给丢弃掉了。此时你也就看不到响应。当然也是有可能绕过他们的。
国内的互联网公司为什么不去国际上呢
一方面因为国际上竞争能力强主要方面还是因为基础设施如果非洲的经济能跟上基础设施起来了那么这些互联网公司都是会产生的。中国美国这样的国家就给落后地区打了个样落后地区怎么发展就是参考先发展国家走的路。非洲这样的地区它的基础设施没跟上所以先过去的就是手机笔记本台式机..尤其是手机过去的更多是传音手机这样的主要进行打电话拍照。等他们基础设施起来的时候一定会有3G4G这样的手机过去的。
路由
在复杂的网络结构中, 找出一条通往终点的路线;
路由的过程, 就是这样一跳一跳(Hop by Hop) 问路 的过程. 所谓 一跳 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间. IP数据包的传输过程 IP数据包的传输过程也和问路一样. eg:比如你刚上大学你的大学是北京理工你千里迢迢的去了被北京当你刚下火车的时候你不小心就把手机钱包都丢了丢了以后你身上就剩下几块钱现在你就想在从火车站到北理工这条路你要做一个路径选择因为你没有地图所以你只能去问人在现实生活中问人的时候有可能别人拒绝你因为人家也不知道路。但是在路由器中进行路由转发的时候是一定不会出现路由器拒绝报文的现象的这个路由器肯定会帮你如果不帮你就说明这个路由器内部有bug。 所以当你问人的时候(假设你问了一个大爷)别人给你的答案一共有3种 1.大爷听到你要去北理工他如果知道他就会在自己的脑海里搜索然后就告诉你眼中这条路直走100米然后有个汽车站然后你再去问下在那里等车的人那些人就经常去北理工你问下他们吧。所以这个大爷就告诉了我们一个答案你现在应该下一跳去哪里也就是告诉你下一跳路由应该去哪里。2大爷思考了一下说我也不知道但是你看到那个大妈没那个大妈对路熟得很我不知道去北理工的路应该怎么走但是我知道这个大妈肯定是知道去北理工的路怎么走所以你去问大妈吧。这种结果就是大爷不知道该怎么走但是大爷知道谁可以帮助你就把你转发到了另外一个路由器。3.此时大爷上下打量了你一番大爷亮出一块牌子上面写的是北京理工大学这个大爷是北理工的保安大爷就告诉你同学不用在找了这就是北理工的门口。其中对你来讲虽然你已经到了北理工但是你的路由还没完所以我此时就紧接着又问大爷“18号宿舍楼该怎么走”大爷就告诉你沿这个路直走直走之后上面有楼号你就看见了。此时你便顺利的到达了北理工并且顺利的到达了18号楼。第一种情况就是大爷知道下一跳怎么走这叫做你的数据包经过大爷思考的过程就是根据你的目标地址做了一次路径查找思考完之后得到的结论就是下一跳应该去哪里。第二种情况就是大爷不知道下一站应该去哪个路由器但是大爷知道如果自己查不出来此时就应该跳转到下一跳叫做默认路由器。所以第二种查找结果就是问了一个大妈如果查路由表没查到每一个路由器都配有自己的默认下一跳。第三种情况我们就称之为你所要去的目标网络的入口路由器在你没有达到入口路由器之前你在进行路径转发的时候你最常规的就是得到两种答案一种下一跳应该去哪一个第二种默认路由。 所以对我们来讲实际在进行根据目的ip去做路径查找的时候我们是先根据目的ip地址先根据目标网络先找到目标网络然后再根据目标网络所对应的入口路由器再将我们的报文进行内网转发到达目标主机这是路由的宏观思路。 IP数据包的传输过程也和问路一样. 当IP数据包, 到达路由器时, 路由器会先查看目的IP; 路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;发送给下一个路由器有两种情况1.转发给的下一跳路由器是明确的 2.查完之后没有只能把你放到下一跳依次反复, 一直到达目标IP地址。然后就进行所谓的内网转发为什么我经过不断的去查找路由表直接就可以不断的去跳转到下一跳然后找到目标网络呢 1.首先路由表的建立路由表的条目肯定是让我们查找的范围越来越小的。 2.我们不断在查找的过程中当时人家在做网络建设的时候已经给我们把各个片区划分好了中间的路由器自己的路由条目是支持我们从一个区域跳转到另外一个区域的这是能做到的所以我们不断的跳转下一跳的过程就是不断靠近目标子网的过程。 全球有很多的子网你每次一跳转到下一个路由器就意味着你放弃了当前你所处的子网也就是你排除了一个子网你不断在查找的时候就是所有的子网不断被排除的过程这样最终你总是会找到你想去的子网的。实际上这个与我们的网络建设是有很大关系的从一个局域网出来的数据是会被扔到我们对应的路由器构建的子网当中的在路由器内因为路由表已经构建好每个路由器都认识路径的全貌所以路由器就可以进行路径转发。 那么如何判定当前这个数据包该发送到哪里呢? 这个就依靠每个节点内部维护一个路由表 eg1:我们在云服务器上的route命令就显示出OS维护的路由表 Destination就代表路由器直接连接的目标子网Gateway表示路由器Genmask叫做子网掩码Flags: U表示它当前正在被使用G表示这个东西是个路由器Iface代表路由器所对应的接口因为我们今天是一台服务器所以它的接口只有一个。实际上路由器至少两接口要不然路由器怎么配两个ip连接两个网络呢。Iface的意思就是说将来你可以通过这个接口来收发数据。比如我有一个要去10.0.8.3这个ip的报文被我这台路由器收到了然后就去查路由表。因为表里面有2条记录我就拿着这个ip地址和任意一个条目配置的子网掩码(子网掩码的长短就设置了子网路由器就是根据子网掩码构建的子网)按位与此时就得到了10.0.8.0 这样的目标网络然后和Destination做对比发现要去的就是这个目标网络然后就直接把你这个报文通过eth0这个接口扔出去此时就完成了一次路由表的查找。 如果是要去127.17.0.2这个ip的报文被我这台路由器收到了还是分别与这2个条目作对比查完路由表发现你的目的网络经过子网掩码按位与并没有匹配的Destination最后我们直接就default此时我们就可以直接把这个报文扔给默认下一跳了。 这个例子没有体现出来我下一跳应该去哪个路由器的问题因为这个路由器是家用级别的一个路由器如果是在运营商内部的一些路由器它是要帮你完成各种数据包转发的。比如说有可能运营商在判断的时候它就知道你一定是要把数据转发到公网当中但是有时候我们在运营商内部就是想把数据转发到另外一台主机虽然这种技术难实现但是这种技术确实可能存在。所以运营商在做路由查找的时候做判断你要去的目标网络如果是外网虽然我不知道你要去哪个外网但是我知道你不是我本主机所以我就直接把你扔到我的路由器了如果你要内网当中我就要把你转发到下一跳另外一个子网的入口路由器当中。 eg2:假设某主机上的网络接口配置和路由表如下: 这台主机有两个网络接口,一个网络接口连到192.168.10.0/24网络,另一个网络接口连到 192.168.56.0/24网络; 路由表的Destination是目的网络地址,Genmask是子网掩码,Gateway是下一跳地址,Iface是发送接 口,Flags中的U标志表示此条目有效(可以禁用某些 条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发; Geteway中打星号的就是一个网络如果是具体ip或者是default这种的就代表默认路由对应的下一个设备。转发过程例1: 如果要发送的数据包的目的地址是192.168.56.3 跟第一行的子网掩码做与运算得 到192.168.56.0,与第一行的目的网络地址不符 再跟第二行的子网掩码做与运算得 到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去; 由于192.168.56.0/24正 是与eth1 接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发; 转发过程例2: 如果要发送的数据包的目的地址是202.10.1.2 依次和路由表前几项进行对比, 发现都不匹配; 按缺省路由条目, 从eth0接口发出去, 发往192.168.10.1路由器; 由192.168.10.1路由器根据它的路由表决定下一跳地址; 所以对我们来讲路由表查找的过程实际上是根据路由表的条目来一个一个做转发的这个时候我们在重新回过头以下图为例 当你发起请求时(目的ip是122.77.241.3)你自己的OS也有路由表然后拿着目的ip和去查当前OS的路由表发现这个报文要去的目标主机根本不在我这个局域网上然后就直接可以交给家用路由器家用路由器也可以自己做路由表查找然后再做路由你要去的目标网络还不在当前主机就把他扔给运营商路由器在广域网当中还有可能有很多很多的中间路由器比如跨区的跨省的跨国的...经过转发找到目标路由器。本质上每一个过程都是查路由表的过程。 当然路由表在构建的时候肯定也不是随便构建的我们的网络是经过精心设计的只要一个报文在不断的对外转发的时候它一定是无限性的趋近于自己的目标网络的。 ps:目的ip是127.0.0.0本地环回这样的报文实际上是不会经过网络的它实际上是把协议栈走了一圈向从上到下交付了一下到了网络层这就查自己的路由表发现就是给自己的然后自己就把报文自底向上交付了所以它其实没有转发没有发就体现在它其实是没有把数据交付给数据链路层的。 路由表生成算法 路由表可以由网络管理员手动维护(静态路由), 也可以通过一些算法自动生成(动态路由). 请同学们课后自己调研一些相关的生成算法, 例如距离向量算法, LS算法, Dijkstra算法等. 数据链路层 对比理解 数据链路层 和 网络层 目前我们已经有了一种把数据经过网络经过路径选择将数据跨网络传送到B主机的能力它是通过子网划分运营商进行网络建设路由表构建网络以及报文根据目的网络进行路径查找综合给我们提供的这种能力让我们能够把报文经过路径转发送到主机B我们的ip不提供可靠性因为报文丢失了不担心因为ip头上就是TCP一旦ip失败了长时间得不到应答那么TCP就会直接重发刚刚的报文对应的就是ip报文被重发了因为ip具有这种能力的意义就在于它有较大的概率将数据发送到主机B所以如果我们丢包了没关系重传一下就可以了这就叫做TCP/IP综合的提供了这样的能力。 ip最重大的意义在于路径选择 ip最大的意义不在于报文一个个的转发而在于路径选择查路由表的过程实际上是在进行路上决策我们应该要把我们的报文转到下一跳还是怎么样解决的是路径选择的问题就好比我们的ip提供了把数据包转发过去这样的能力但是要把数据从主机B到达主机C这个是ip层给我们提供的一个跨网络传输的能力但是ip要把数据从主机A到C你得先经过路由选择先把数据从A交给路由器A然后再交给路由器B再到C再到D经过一跳一跳转发才能到达主机C。 你为什么要把数据包由路由器A交给路由器B呢 这是由目的ip决定的目的ip是由目的网络和目标主机构成。 如何把数据包由路由器A转到路由器B呢 数据链路层解决的 ip最大的意义在于经过每个路由器的时候进行路径选择的时候是ip负责的而把报文经过决策之后要跳转到下一跳如何跳转是Mac帧决定的为什么要跳转是ip决定的。 TCPIPMAC帧每一层起的是不一样的作用TCP保证可靠的把数据转到对面ip给你提供路由的能力让你能做路上的决策数据链路层给你提供路上把一个报文转到下一个报文的能力。然后我们就具备了将一个数据可靠的从一端送到另外一端的能力。 凡是能够跳转到下一跳一定是直接相连的节点直接连接的节点一定是在同一个网段(局域网)。所谓的网络就是无数个局域网通过一些横跨局域网的路由器连接起来的大网络。所以所谓的路由转发的本质就是将数据包从一个局域网不断经历中间若干个各种局域网的过程。 我们接下来研究的就是局域网通信的问题 同一个局域网两台节点能直接通信吗 当然能。 eg:博主的手机和电脑连接同一个局域网进行互传文件(依靠手机端的远程连接功能) 因为电脑和PC都连接的校园网属于同一局域网所以他俩可以进行通信。 如果手机用流量电脑用WiFi此时他俩就不在同一局域网了也就不能进行通信了 局域网通信 局域网通信常见的有以太网或者令牌环网。博主重点讲解以太网之后提到的局域网都是以太网 以太网的通信原理 在同一个局域网任何一个时刻每台主机都是首先连接的我们对应的局域网你可以把局域网相想象成一根大的网线把所有的主机都连接起来了一个主机想给另外一个主机发消息直接就把资源扔到这个网线上就可以了这个资源当中的数据是被所有的主机全部都能收到的所有主机全部收到了但是所有的主机会对比自己主机的Mac地址发现数据填充的Mac地址不是自己的所有主机都会丢弃只有目标主机会接收此时目标主机就收到了这个数据此时就完成了一次单向转发。局域网的这块网络资源是被所有主机全共享的意味着我们不允许多台主机同时向网络中发消息此时就有了碰撞检测碰撞避免算法来保证任何时刻只允许有一个人向局域网中发数据。换言之以太网的通信标准是通过概率通过尝试去进行的。 局域网是通过碰撞检测和碰撞避免完成的我们一般把这个局域网就叫做碰撞域如果你想黑掉这个局域网无非就是向局域网里塞垃圾数据。 以太网帧格式 网络协议是分层的最顶层是应用层然后是传输层网络层数据链路层。应用层产生一个数据是会添加自己的报头的向下交付给传输层传输层加上自己的报头向下交付给网络层网络层在添加自己的报头向下交付给数据链路层。数据链路层再添加自己的报头最后形成的这个玩意我们称之为数据帧。 源地址和目的地址是指网卡的硬件地址(也叫MAC地址), 长度是48位,是在网卡出厂时固化的; 帧协议类型字段有三种值,分别对应IP、ARP、RARP; 帧末尾是CRC校验码之前我们讨论分片的时候说过Mac帧要求上层传送的数据包不能太大规定就是1500字节数据包太大就要求分片哪怕分多次发也不能太长。网络层交付的整个ip报文整个就会全部包裹在数据帧的有效载荷当中在数据链路层这整个ip报文就被称之为数据了。 如何分离报头和有效载荷(封装)
因为它采用的是662 结尾4。
所以头部加14个字节尾部4个字节的数据就完成了封装。
解包的话就是定长的报头。18字节。
如何决定将自己的有效载荷交付给上一层
通过类型字段来决定。
认识MAC地址
在局域网中转发数据的时候一旦决定了我下一跳要去哪里那么ip就没有意义了接下来我们在局域网转发的时候我们就叫做如何把数据包转发给下一跳我们用的就是在同一个局域网中对应的MAC地址。
MAC地址是48位 ether代表以太的意思点分十六进制的风格就是48个比特位。MAC地址是在网卡当中已经内嵌好的是网卡厂商在出厂的时候已经帮我们把对应的MAC地址已经写好了所以每个主机都有唯一的标识符来标识该主机。 所以数据帧中目的地址指的就是目的Mac地址就是6个字节。源MAC地址代表的就是这个地址是哪个主机发的。它俩就代表这个数据帧是哪一个主机发的要发给哪一个主机。
类型字段
类型字段决定我的这个有效载荷里装的是什么
有点像邮寄包裹的时候贴的一张纸写的是易碎物品轻拿轻放它就告诉我包裹里面装的数据类型。
如果这个里面填的是0800(16进制的写法)就叫做里面的类型是ip数据包。其实在数据链路层之上网络层之下其实也是在链路层它上面还有一些有用于管理的协议叫做ARP协议所以数据链路层既可以把数据包交给网络层也可以了交给同层当中它的数据帧上一层的协议叫做ARP协议。0806代表的就是ARP8035代表的就是RARP。
类型决定有效载荷是什么我就可以根据类型决定将我的有效载荷是交给上层的ip还是交给ARP协议。
CRC校验字段
CRC校验字段就是在一个偏硬件的程度上来对我们所谓的数据进行相关的校验工作。这个校验工作通常是看我们的数据帧有没有问题比如比特位翻转或者发送碰撞出现错乱的问题。
再谈局域网
局域网通信能力的存在是为了支持跨网络转发的也就是支持ip的ip要能够跨网络转发到目标主机又是为了支持TCP进行可靠性保证的。这些所有的过程都叫做通信细节。
eg:局域网转发过程
主机A的Mac地址是MA主机B的Mac的地址是MB(假设主机B就是路由器)。他们两个要通信一个ip报文下达到主机A然后就在数据链路层开始转发主机A的数据帧类型这里填0800目的Mac地址填写的就是MB源Mac地址就是MA数据有效载荷就是ip报文。然后我就把这个数据帧扔到网络里面了接下来你就应该把数据交给物理层所以实际上开始的就是硬件的操作。然后这个局域网里所有的主机都能收到数据帧大家收到的时候每一个人都要先进行解包提取目的地址发现是MB所以除B主机外的所有主机在自己的Mac帧层就丢弃了。每一台主机都有自己的协议栈拿到数据的是协议栈最底层的数据链路层拿到的拿到之后对比自己的Mac帧发现不是就直接丢了报文丢弃了也不会向上交付。所以除B主机外的所有主机压根就不知道自己曾经收过这个数据帧。B路由器收到数据进行解包发现目的地址和自己相等然后根据类型发现是0800然后将自己的数据交给网络层因为它自己是给路由器所以就不在解包了然后自己提取出数据中的路由的目的ip查路由表发现这个东西要到下一跳了下一跳又是一个节点到另外一个节点然后又要向下交付然后就重新再次封装Mac帧然后再交给下一跳路由器。这就叫做局域网的通信。所以局域网的通信根据Mac帧做目的地址对比就可以了。
只有有了局域网的技术才可以将所有的局域网集联起来构成广域网所以所谓的路由转发无非就是决策将数据从一个局域网转发到另外一个局域网因为路由器的存在它可以调节至少两个网络网络里存在大量的路由器那么大量的局域网就被连接起来了。实际上无线LAN和令牌环已经不重要了因为有ip地址的存在所以实际上就可以屏蔽掉底层网络的差异统一使用ip地址。路由表在路由的时候一定经历了一次解包和重新封装的过程路由器有两个网络接口左侧是以太网右侧是令牌环不影响因为路由器一定既装了以太网的驱动程序又装了令牌环网的驱动程序所以当他解包时是按照以太网进行解包的当他路由之后知道我要跳转到下一跳重新去封包的时候 因为另一个接口接的是令牌环网所以它封的肯定是令牌环的报头。所以站在网络层网上看所有的网络都没有差异全都是ip网络。
有效载荷
以太网的数据帧的有效载荷最少不少于46字节最多不超过1500字节。如果有效载荷太少的话我要给你添加padpad叫做填充意思就是随便给你加的值只要凑够46以上就可以。因为传送太少的话可能会出现问题。
在局域网中做数据转发的时候是基于碰撞检查碰撞域这样的策略去做的所以为什么数据帧的物理层为什么要规定1500字节(虽然这个值可以改大也可以改小但是基本上都是1500)
如果不规定上限的话我们的数据帧可以很大很大的时候意味着上层就可以交下来很大的数据也就意味着主机发送的数据帧可能会很长数据帧很长的话也就意味着在物理层光电信号发送的时候它可能需要较多的时间那么就意味着一个数据帧在网络里进行转发的时候它占据的一个单位时间就会变的长了在单位时间内变长就可能增加局域网冲突的概念所以数据帧一定是尽快发送。别人没有发送数据的间隙肯定是比较短的时间越短其中你可发的数据量就越少要不然就冲突了。所以数据帧有上限一定是根据对应的硬件考量实验出来的所以一定需要我们遵守。不要认为1500就是慢如果是1500以上那么一旦出现了拥塞丢包那么你重传的量也大所以不能无脑增大要考虑全面。
认识MAC地址
MAC地址用来识别数据链路层中相连的节点; 长度为48位, 及6个字节. 一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19) 在网卡出厂时就确定了, Mac地址是内嵌在网卡当中的Mac地址是网卡当中的某一种序列化只要保证网卡中Mac地址不重复就可以了不能修改. mac地址通常是唯一的注意这里的全球唯一指的是真实的硬件也有一些技术可以虚拟出Mac地址比如虚拟机可以虚拟出设置一些网卡。所以你想伪造一个网卡在局域网中也是可以的因为Mac地址根本不会跨网络传送你这个Mac地址只在你的 局域网中可以被其他的主机采纳使用一般不会跨网络传送所以我们伪造的时候只要和别人不一样就可以了(虚拟机中的mac地址不是真实的mac地址, 可能会冲突; 也有些网卡支持用户配置mac地址).
对比理解MAC地址和IP地址
IP地址描述的是路途总体的 起点 和 终点; MAC地址描述的是路途上的每一个区间的起点和终点;
一个是广域网的概念一个是局域网的概念一般在整个路由转发的时候Mac地址是一直在变的因为经过一个设备要重新解包和重新封包因为要经过路由器路由器要向上交付路由表可是在网络层的数据链路层收到数据帧要重新解包到网络层网络层提取出ip地址做路由查找知道下一跳要去哪里了然后在重新封装所以Mac地址一直在变化而ip地址一直不变。但是实际上是目的ip一直不变源ip有可能发生NAT替换。认识MTU MTU相当于发快递时对包裹尺寸的限制. 这个限制是不同的数据链路对应的物理层, 产生的限制. 以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位; 最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU; 如果一个数据包(ip层每个层的报文有不同的名字)从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation); 为什么不让数据帧做分片呢 如果数据帧做分片那么报头就得改数据帧配套的协议就得改协议改了驱动就得改驱动改了那么硬件就有可能也要变。我们肯定是更愿意去改软件。所以多我们来讲我们把他交给网络层让ip去改可以说是众望所归。 不同的数据链路层标准的MTU是不同的; 强制解调器是什么呢 我们一般在局域网中通信的时候是有很多的数字信号或者模拟信号比如说数字信号在运营商发的时候是需要经过我们所谓的强制解调器把数字信号到模拟信号进行互相转化的因为在硬件传播上是有差别的强制解调器就是做这个事情的。 MTU对IP协议的影响 由于数据链路层MTU的限制, 对于较大的IP数据包要进行分包. 将较大的IP包分成多个小包, 并给每个小包打上标签; 每个小包IP协议头的 16位标识(id) 都是相同的; 每个小包的IP协议头的3位标志字段中, 第2位置为0, 表示允许分片, 第3位来表示结束标记(当前是否是最后一个小包, 是的话置为1, 否则置为0); 到达对端时再将这些小包, 会按顺序重组, 拼装到一起返回给传输层; 一旦这些小包中任意一个小包丢失, 接收端的重组就会失败. 但是IP层不会负责重新传输数据曾经我们讨论分片的时候是以端到端(从自己的主机到对方的主机)的方式去讨论的。 因为这是最简单的实际上我们现在就知道了当我们的数据包在路由转发的时候你的主机规定是1500它的主机规定也是1500我经过的路上的路由器有可能路上的路由器本身的mtu可能就是500所以在你主机经过路由器转发的时候进来是1个报文出去就可能是3个报文了所以在路上也有可能分片。
如果在路上分片了接收端主机该如何合并呢
不要担心最关键的就是13位片偏移如果你的报文在路上也片偏移了原始的报文有原始的片偏移如果你再分片我给他分片的子分片偏移量我曾经的片偏移那么子的片偏移量就不是0。所以虽然报文变得很细但是每一片采用的片偏移依旧是在原始当中的片偏移位置。
eg: 分片的过程上层协议不关心也不知道。一旦过多分片就有可能导致丢包的概率增加。
MTU对UDP协议的影响
让我们回顾一下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字节变长选项中(kind2);
虽然TCP不能发太大的报文但是不意味着TCP不能发大量的报文。我们来算算
数据链路层规定1500我们不考虑携带选项这样的概念也就意味着会影响网络层网络层的标准报头20自己所以网络层的有效载荷就是1480。TCP的标准报头也是20个字节也就要求传输层有效载荷只能是1460。传输层的1460就是用户交付给的字节数。换句话说应用层定义了1M数据一次就通过send发出去实际上你把数据全部拷贝到TCP的发送缓冲区里你以为你发了1M实际上TCP不可能一次把1M全部发出去他只能1460,1460...一个一个的包裹进报文经过数据链路层转发出去。
所以应用层叫做用户下三层叫做内核层内核处理通信细节用户不关心。
路由器如何跳转到下一跳
在进行路由转发的时候实际上是把数据从一个局域网交个另外一个局域网通过一个子网交给下一个子网子网和子网间跳转是通过路由器因为路由器至少连接两个子网。子网之间的关系是由运营商划分好的。 如果这个数据包跳转到目标子网的入口路由器因为路由器D和主机B是属于同一个局域网的属于同一个局域网把数据从路由器D交给主机B是要封装mac帧的所以我们就得需要知道对方的目的以太网地址的但是目前这个数据包被路由器D收到了但这数据只知道要去的主机的目标地址是ipB但是这个报文里并不涵盖你要去的主机B的mac地址而且路由器D也不能确定当前的这个ipB它对应的mac地址是谁也就是说路由器D只知道这个报文的目的ip而要把这个数据包交给主机B就必须得知道它的mac地址因为我们要封装Mac帧。怎么办呢 直接进行广播在局域网中要进行局域网广播只需要将以太网目的地址设置成全f那么这个数据帧就会被局域网内的所有主机收到这就是广播。可是广播不准确你只想发给主机B。再者广播给所有人是会影响别人的。 当然广播之后到达ip层对比ip地址如果不对了就直接在ip层丢弃看起来好像可以但是实际上我们并没有这么干。比如你的路由器积压了很多报文都是发给主机B的可是主机B被拔网线了然后路由器分配地址的时候把主机B曾经的地址分配给主机A了这个时候路由器曾经积压的数据就全部发给主机A了。这就有问题了。 广播缺点广播方式会产生大量流量导致带宽利用率降低进而影响整个网络的性能。 当需要网络中的所有主机都能接收到相同的信息并进行处理的情况下通常会使用广播方式。 现在的问题是你把这个报文转发过来可是你只知道这个报文要去的目标主机ip而你要把数据单向的交给主机B你必须得有对方的mac地址。 ARP协议
如何在网段中通过ip地址获得该主机对应的mac地址 我们就需要一种ARP协议叫做地址转化协议是把你要的ip地址转化成对应的mac地址 ARP协议就是一个在局域网内发现每一台主机对应的Mac地址的一个通信协议。 eg:今天老师还是在教室上课老师现在不知道有一名同学叫张三但是老师知道每一名同学的学号今天老师想和学号是10号的同学进行聊一聊老师就说10号同学请你告诉我你的名字。此时这条消息在教室的所有同学都听到了大家里面就在对比着自己的学号最后只有学号是10号的同学站起来了就说老师我是10号我的名字叫张三。老师就知道了10号的名字从此以后老师就不在叫他10号了而是直接叫他的名字张三。同理老师就可以通过这种方式知道其他学号学生的名字了。所以老师知道学生的学号就可以通过学号的方式来首先获得同学的名字。换句话说老师知道的同学们的学号就相当于在局域网内同学们的ip地址知道了同学的ip地址就可以通过ip交换你的Mac帧。其中交换原理就是我先拿着你的ip进行广播我们子网中谁是10号主机 因为是广播信息所有主机都要收到这个信息并解包并且都要处理处理之后向上交付的时候如果发现这个信息包含的请求的ip地址不是我就直接丢弃。如果是我就进行保留然后再给目标主机单向的发送一个我是10号主机我的Mac地址是多少你可以给我通信了。此时我们就完成了一个Mac地址交换的问题。 路由器D是如何知道主机B的ip地址呢
1.入口路由器D收到的报文是包含了目标ip的。而且你要去的目标主机一定是在这个目标网络中的主机肯定在。所以我就已经拿到了目标网络内目标主机的ip地址。
2.即使路由器D不知道主机B的ip地址也可以局域网就规定了网络情况不是特别大基本上一个局域网内最多几百台而且大家的网络号一定是一样的主机号不一样。比如说我这个局域网内有254台主机(8位主机号)我路由器直接通过某种方式直接把局域网内所有主机遍历一次相当于拿着你的ip地址从1-254遍历一下所有的主机相当于给主机发报文其中我就能知道所有主机的ip地址了。
ARP协议的作用
ARP协议建立了主机 IP地址 和 MAC地址 的映射关系. 在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址; 数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃; 因此在通讯前必须获得目的主机的硬件地址;
ARP协议的工作流程
对我们来说现在的问题是知道你的ip但是不知道你的Mac地址所以我们可以在局域网内进行ARP。 这里就是一个先广播再单发的问题。
源主机发出ARP请求,询问“IP地址是192.168.0.1的主机的硬件地址是多少”, 并将这个请求广播到本地网段(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF表示广播); 目的主机接收到广播的ARP请求,发现其中的IP地址与本机相符,则发送一个ARP应答数据包给源主机,将自己的硬件地址填写在应答包中; 每台主机都维护一个ARP缓存表,可以用arp -a命令查看。缓存表中的表项有过期时间(一般为20分钟),如果20分钟内没有再次使用某个表项,则该表项失效,下次还要发ARP请求来获得目的主机的硬件地址
ARP数据报的格式 在数据链路层我们经常用的是mac帧协议mac帧协议除了直接可以交付给网络层协议外在Mac帧之上有一个协议我们称之为ARP。ARP协议只是在数据链路层的一个协议它虽然在Mac帧协议的上层但是它不属于网络层只属于数据链路层。Mac帧收到数据帧之后可以把数据交给网络层对应的ip也可以交给自己的ARP协议它交给ARP协议取决于Mac帧对自己的有效载荷的判断(也就是当我们进行ARP请求的时候交给ARP协议完成工作之后ARP协议不会交付给网络层而是再向下交还给Mac)。相当于这个ARP协议属于数据链路层底层自动完成的一个协议叫做ARP。对我们来讲只要我们在进行ARP请求的时候这个数据帧一定根据它的帧类型交付给它的ARP协议至此就完成了数据帧转发的功能也不在向上交付。 像这种不断向上交付的数据我们更多的谈的是用户数据这种类型ARP不向上交付的是管理数据说白了就是这个ARP协议就是用来处理ARP请求的本身就属于数据链路层它不会向上交付。 红色框这部分是由ARP协议去形成的换句话说ARP协议的整个数据报文是作为数据帧的有效载荷被数据帧封装了。所以Mac帧要封装ARP协议ARP协议一定是在Mac帧上层。而且ARP协议里都是一些网络中的概念没有有效载荷因为ARP协议不需要向上交付。所以每一个大层里面还可以细分成各种各样的小层。 ARP的请求大小是28字节28字节不够数据帧的46字节(利用PAD字段进行填充)。注意到源MAC地址、目的MAC地址在以太网首部和ARP请求中各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的。 硬件类型指链路层网络类型(例如以太网令牌环网无限WiFi我们这里只谈以太网),1为以太网; 协议类型指要转换的地址类型,0x0800为IP地址; 硬件地址长度对于以太网地址为6字节; 协议地址长度对于IP地址为4字节; 前面4个字段都是填好的就不用在管了op字段为1表示ARP请求,op字段为2表示ARP应答 发送端以太网地址和发送端ip地址就是填充我的MAC地址和IP地址。目的以太网地址我不清楚所以这个字段就填充成全F意味着这个字段是未知的。目的IP地址我也知道。 如果是ARP请求的时候只有目的以太网地址这个字段我们不清楚。 PS ARP协议也要封装mac帧也要走局域网通信原理一定是向下交付的。ARP请求里要填ip地址实际上这个ip字段是上层去填写的因为是上层收到了一个ip报文上层要发起数据但是因为没有mac帧所以上层只能先ARP所有的协议虽然都在数据链路层但是一定要有人主动发起所以上层再发起ARP的时候就可以把对应的ip地址作为参数传给ARP协议这个时候就可以向下传。有时候各种层之间也需要彼此的数据交互。ARP传输过程 我们的A就是一个入口路由器收到了一个报文它的报文中携带的只是目的ip是IPB。当主机A收到一个网络报文发现它要去的是IPBIPB通过自己内部的路由表然后通过目的IP和子网掩码按位与得到目标网络发现你要去的目标主机和我这个路由器是直接相连的你已经到达了入口网络了到达了入口路由器现在我这个路由器就负责把这个数据内网转发到主机B(也就是局域网转发到)可是我这个路由器并不知道主机B的Mac地址所以此时主机A就先发起一次ARP请求获得主机Bmac地址当然这个路上也一定用属于同一局域网的其他主机。然后主机A就开始填写ARP请求硬件类型就是1协议类型就是0800硬件地址长度就是6协议地址长度就是4op就是1发送端以太网地址就是MACA发送端的IP地址就是IPA目的以太网地址就是全F目的IP地址就是IPB(因为报文里面就是IPB)。填好以后这个ARP请求就要向下交付封装mac帧就需要填写以太网的各种字段以太网的目的地址就是全F(因为我们不知道在数据链路层中封装的数据帧是全F就叫做广播)源以太网地址就叫做MACA帧类型就是0806(代表ARP请求或者应答)。 所以此时就构成了一个完整的数据帧就通过网络被广播到局域网中所有的主机就全部都能收到了包括主机B大家发现这个目的Mac地址是全F(广播)所以所有的主机就进行处理mac帧报头和有效载荷分离提取出帧类型发现是0806然后所有主机都把这个报文解包之后交付给自己的ARP协议。 主机拿到ARP后先对比目的IP地址是自己的就处理不是自己的就可以在自己的ARP层把ARP请求全部丢弃理论上确实是这样的可是任何局域网中的主机可能向别人发起ARP也可能被别人发起ARP如果被别人发起ARP意味着此时的ARP一定是一个ARP请求别人是请求我的如果我向别人发起ARP我极有可能得到的是一个ARP应答。所以你发起一个ARP请求不要认为就完了你还要让别人把ARP应答给你但是任何一台主机都有可能承担这两种角色。 eg:主机B收到了一个ARP但是主机B必须得知道这个ARP是请求还是应答因为如果是请求就得给别人构建ARP了如果是应答我就要拿出来对方的mac地址然后给对方发数据报文了。所以当我收到一个ARP请求我一定是先看OP字段的OP字段表明的就是这个ARP协议是请求还是应答。 所以主机B拿到ARP后看见这个OP字段为1所以就立马意识到这个是ARP请求然后再看目的ip地址发现就是自己然后就要进行ARP的应答了。至此就完成了ARP的请求过程。 接下来主机B就要开始构造应答了ARP的硬件类型就是1协议类型就是0800硬件地址长度就是6协议地址长度就是4op就是2发送端以太网地址就是MACB发送端的IP地址就是IPB目的以太网地址就是全MACA目的IP地址就是IPA(ARP请求里就有A主机的mac地址和ip地址)。然后主机B在向下交付封装数据帧报头。以太网的目的地址就是MACA源以太网地址就叫做MACB帧类型就是0806(代表ARP请求或者应答)。接下来这个信息就被主机B发送到网络里这次虽然不是广播但是所有的主机还是都能收到只不过这次所有的主机收到数据帧分析报头目的主机是MACA除A外的所有主机就全部丢弃了(在数据帧层丢弃)这次的丢弃就是正常的局域网通信数据帧不是自己的。所以主机A就收到了数据。主机A收到数据就解包解包之后知道这个数据是MACB给我发过来的然后根据帧类型0806识别到是一个ARP然后就把有效载荷交给主机A的ARP协议。在主机A在ARP层同样先看OP字段发现是2应答接下来看的就是发送端以太网地址此时主机A就获得了主机BMac地址进而就可以进行封装IP报文单向的把数据从A发到B 为什么收到ARP后要先看OP字段而不是看目的IP字段
主机拿到ARP后先对比目的IP地址是自己的就处理不是自己的就可以在自己的ARP层把ARP请求全部丢弃理论上确实是这样的。
但是你不能确定这个目的ip是你想要的数据你必须得先知道这个是ARP请求还是应答你才能决定你接下来要关心哪个字段。
比如ARP应答压根就不关心目的IP因为接收方只要判断出ARP是应答这个目的ip就是它自己所以我们必须先得找到op才能决定关心哪些字段。
主机A收到来自主机B的数据帧为什么不直接从以太网首部这里提取主机B的mac地址呢
理论上从这里提也可以但是你收到的主机B的数据帧在数据链路层并不清楚这个数据帧和哪个ip对应没有ip对应的话也就没有实用价值因为你封装的报文都是给ip服务的。ARP协议里既有mac地址又有ip地址就是为了告诉你mac地址和ip地址的映射关系所以当上层下来的时候我们就可以根据ip找到mac地址然后封装我们对应的数据包。
这个路由器D可以在局域网中发起一个ARP然后路由器D就可以拿到主机B的mac地址所以数据包此时就跟据目的ip知道了我要去的目的mac地址所以再封装mac地址就到了目标主机。
ARP的过程不仅仅在我们对应的入口路由器和目标主机之间有比如路由器A想到路由器B路由器这个设备天然的就会自动发现主机说人话就是在局域网内根据自己的目标网络不变然后自己从1开始遍历主机号相当于给没台主机直接发送ARP遍历的时候就发现了局域网内所有的主机了。换句话说就是路由器A在路上的时候就有可能找不到路由器B此时就只知道路由器B的ip地址此时就发送ARP。任何时刻在路上的时候都可能ARP。
主机A经过路径选择到达了入口路由器然后到达主机B难道每一次向主机B发消息都要进行ARP请求吗
第一次向主机B发消息入口路由器需要发送ARP获取主机B的mac地址。那么第二次第三次...每一次发送消息都需要发送ARP获取主机B的mac地址吗答案是不需要。这个ARP在局域网其实是很快的但是路由器D不是只给主机B发消息的可能给局域网内的所有主机都要发消息如果每次都要ARP就意味路由器太忙了所以对路由器来讲ARP是一个特别低效的东西。
ARP缓存表
实际上系统当中是会针对ARP的ip地址和mac地址做缓存的。
查看缓冲的命令arp -a 我们在正常通信的时候只有第一次通信的时候需要发送ARP就认识主机了。之后我们就可以直接查ARP缓存然后就可以直接找到目标主机。
我可以将这个ip和mac地址永久保存起来吗
不可以 主机B现在是一个健康状态。如果路由器永久的把ARP的ip和mac地址映射的关系保存起来先不谈ip地址变化的问题就是IP地址不变主机B有一天网卡坏了那么此时就直接把主机B的网卡更换了此时主机B的mac就变了。如果你的路由器写死了永久保存了那么这个主机B也就永远上不了网了(至少在这个局域网内)。所以这个缓冲一定要有时间限制一般比如10~20分钟是有效的时间到了系统就自动清理掉。让主机B有再被发现的可能。所以这个ARP缓冲是以分钟为单位进行缓存只要一直访问就可以一直给你映射只要时间到了就会自动把他清理掉清理掉之后下次请求时就会在进行ARP就重新拿到了mac地址。
如果我今天想知道和我处于同一个局域网内所有主机的mac地址怎么办呢 比如这就是我的子网和子网掩码。 通过子网掩码我们可以看出我们的主机数一共是10个比特位也就是2^101024台机器这是因为我们用的是云服务器。 博主学校的校园网的主机数更多一共15个比特位也就是2^1532768台机器。 一般家里的局域网的子网掩码一般是255.255.255.0一般是200多台机器。 所以我自己的ip地址我知道子网掩码我知道 那么我就知道了网络号了主机号我虽然不知道但是我就可以构造一批ip地址。
假设我的ip地址是10.0.8.0 子网掩码是255.255.255.0我要构建ip地址很简单
cnt1; while [ $cnt -le 255 ];do echo 10.0.8.${cnt}; let cnt; done此时我们就把局域网内所有的主机全部罗列出来了。有可能其中有的ip是无效的实际上ARP触发的时候就是我给你发送报文的时候。我只要尝试给这个主机发消息就一定要先做ARP意味着你的ARP的信息一定是会被缓存起来的。所以我可以采用ping的方案(ping就是用来检查网络连通性的检查连通性的本质就是通过给你发数据你给我应答只有你给我应答了才证明你这个主机是连通的我给你发报文就必须知道你的mac地址所以你就必须先ARP)。
换言之我们已经构造出来所有的ip了我就可以直接ping这些个ip
cnt1; while [ $cnt -le 255 ];do echo ping - 10.0.8.${cnt};ping -c1 10.0.8.${cnt}; let cnt;done通过这样的方式我把局域网内所有的主机都ping完只要我ping成功就会给我们对应的ARP然后他的MAC地址就被我们缓存起来了。
因为这样太慢了所以我们写个脚本 增加执行权限
执行完毕后再次查看ARP
我们此时就缓存了一大批的ip与mac地址一共264条(最开始博主的机器只认识10多条现在就认识200多个了)。
RARP
数据链路层上面有个协议是ARP当然还有一个RARP叫做逆地址解析协议。说变了ARP就是把ip转Macrarp就是把mac转ip。
其他重要协议或技术
DNS(Domain Name System) DNS是一整套从域名映射到IP的系统 DNS就是一个域名。当我们实际在访问某一个网址的时候实际上并不是在真的访问这个网址而是你的浏览器首先自动的帮我们进行域名解析拿到ip地址ip地址拿到后此时就拿到了服务器端的ip地址以及你要请求的服务端口进而再去进行网络请求和访问。 PS:DNS则是典型的应用层的协议 DNS背景
TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序. 但是IP地址不方便记忆. 于是人们发明了一种叫主机名的东西, 是一个字符串, 并且使用hosts文件来描述主机名和IP地址的关系.一般这个文件是本地存储的后来由于维护成本太高了就慢慢淡出人们视野了。最初, 通过互连网信息中心(SRI-NIC)来管理这个hosts文件的. 如果一个新计算机要接入网络, 或者某个计算机IP变更, 都需要到信息中心申请变更hosts文件. 其他计算机也需要定期下载更新新版本的hosts文件才能正确上网.
这样就太麻烦了, 于是产生了DNS系统.(有人帮我们做了一个网络服务世界上所有的浏览器在进行请求的时候都要先进行域名到ip地址的转换然后再发起请求)一个组织的系统管理机构, 维护系统内的每个主机的IP和主机名的对应关系. 如果新计算机接入网络, 将这个信息注册到数据库中; 用户输入域名的时候, 会自动查询DNS服务器, 由DNS服务器检索数据库, 得到对应的IP地址.
至今, 我们的计算机上仍然保留了hosts文件. 在域名解析的过程中仍然会优先查找hosts文件的内容.这个文件除了主机会使用外其他情况我们就都不使用了。
cat /etc/hosts 例如你想访问你主机除了ping 127.0.0.1 也可以ping以下名称。 域名简介
主域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称. www.baidu.com 域名使用 . 连接 com: 一级域名. 表示这是一个企业域名(商业公司表示它是以盈利为目的的). 同级的还有 net(网络提供商), org(非盈利组织) 等. baidu: 二级域名, 公司名. www: 只是一种习惯用法. 之前人们在使用域名时, 往往命名成类似于ftp.xxx.xxx/www.xxx.xxx这样的格式, 来表示主机支持的协议.
ICMP协议 网络层中我们都知道有协议叫做ip实际上还有一种协议是在网络层内但属于ip上面的比如说ICMP和IGMP。 实际上有些管理员命令用的是原始套接字他们就能绕过传输层直接去访问网络层的内容相当于直接可以向对端发送ip报文而且不携带用户数据。 ICMP协议是一个 网络层协议 一个新搭建好的网络, 往往需要先进行一个简单的测试, 来验证网络是否畅通; 但是IP协议并不提供可靠传输. 如果丢包了, IP协议并不能通知传输层是否丢包以及丢包的原因 ICMP功能
ICMP正是提供这种功能的协议; ICMP主要功能包括: 确认IP包是否成功到达目标地址. 通知在发送过程中IP包被丢弃的原因. ICMP也是基于IP协议工作的. 但是它并不是传输层的功能, 因此人们仍然把它归结为网络层协议; ICMP只能搭配IPv4使用. 如果是IPv6的情况下, 需要是用ICMPv6;
比如你买好云服务器了你要检测你自己的主机和云服务器是否连通ip协议不提供可靠性丢了就是真的丢了有人说我写个socket用tcp但是现在写个socket也没太大意义因为你现在是要访问它所以我们完全不用UDP和TCP你只要向他发起一个ip报文就可以了但是因为ip报文丢了不和你说要不然怎么会有TCP的超时重传呢所以我们只是用ip向对方发送报文的话如果报文丢了ip协议是不能通知发送方说你把报文丢了及其原因所以我们就设置了一种ICMP协议。
ICMP的最大的特点就是如果你把数据包发送了到了对端主机对端主机关机了这个报文就丢失了当然会经过多次尝试发送发送最后失败的时候就会由最后路由器反向的向发送报文的主机报告发送的情况。以前这个东西时不敢想的因为我们的ip是不提供这个功能的但是因为有ICMPICMP使用IP就能做到这样的工作。说白了就是ping命令底层用的就是ICMP协议说白了就是向对方发送ip报文对方收到ip报文后根据ICMP协议进行应答。
eg:当你ping的时候会看到一些icmp的序号ip报文的TTL(生存周期)time就是来回时间。因为有ICMP这样的协议我们才能看到这些东西。icmp_seq序列号表示第几个个响应包递增的数字。 ICMP一旦将报文发出路由器收到发送数据没发成功ICMP就响应回去路由器响应的原因就是协议规定因为路由器和主机都得遵守协议。最后我们就能得到应答应答报文中是会包含我们不同的错误编码通过错误编码我们就知道它对应的是哪些种类的错误。 ICMP的报文格式
关于报文格式, 我们并不打算重点关注, 大家稍微有个了解即可ICMP大概分为两类报文:
一类是通知出错原因 一类是用于诊断查询ping命令
linux下ping百度 windows下ping百度 注意, 此处 ping 的是域名, 而不是url! 一个域名可以通过DNS解析成IP地址. ping命令不光能验证网络的连通性, 同时也会统计响应时间和TTL(IP包中的Time To Live, 生存周期). ping命令会先发送一个 ICMP Echo Request给对端; 对端接收到之后, 会返回一个ICMP Echo Reply; 一个值得注意的坑
有些面试官可能会问: telnet是23端口, ssh是22端口, 那么ping是什么端口?
千万注意!!! ping命令基于ICMP, 是在网络层. 而端口号, 是传输层的内容. 在ICMP中根本就不关注端口号这样的信息. traceroute命令
也是基于ICMP协议实现, 能够打印出可执行程序主机, 一直到目标主机之前经历多少路由器. 原理也很简单我向你发报文第一次的时候将生命周期设置成1发送出去经过一个路由器转发错了你就给我应答应答之后我就知道是哪个路由器了然后第二次我把我的生命周期改成2依次类推所以我把我的报文的生存周期不断增多这个报文传输的时间越来越远每一个出错丢弃之后都会给我应答直到到达了目标主机这样我就能把整个路径中的所有ip都打印出来。当然这个其实是会变化中短期内路由表的构成是比较稳定的路由选择也是比较稳定的所以路径一般是确定的但是这个肯定是变化的 早上执行和晚上执行都是会发生变化的。 NAT技术 NAT技术背景 我们在进行网络路由转发的时候我们自己的局域网用的是私有ip访问的是公网我直接通过我的家用路由器访问我直接把我的报文中的源ip用路由器的WAN口ip一路替换上去最后我们就能到达目标主机目标主机知道源ip目的ip都是公网ip所以就可以给你做响应返回运营商的入口路由器但是如何回来呢 NAT叫做地址转化协议。 之前我们讨论了, IPv4协议中, IP地址数量不充足的问题 NAT技术当前解决IP地址不够用的主要手段, 是路由器的一个重要功能(所以路由器不光可以进行路由转发桥接多个子网还能在局域网中构建子网进行ip地址的划分与分配(DHCP)还要能够进行NAT现在的路由器甚至还需要进行HTTP) NAT能够将私有IP对外通信时转为全局IP. 也就是就是一种将私有IP和全局IP相互转化的技术方法: 很多学校, 家庭, 公司内部采用每个终端设置私有IP, 而在路由器或必要的服务器上设置全局IP; 全局IP要求唯一, 但是私有IP不需要; 在不同的局域网中出现相同的私有IP是完全不影响的 NAT IP转换过程 NAT路由器将源地址从10.0.0.10替换成全局的IP 202.244.174.37; NAT路由器收到外部的数据时, 又会把目标IP从202.244.174.37替换回10.0.0.10; 在NAT路由器内部, 有一张自动生成的, 用于地址转换的表; 当 10.0.0.10 第一次向 163.221.120.9 发送数据时就会生成表中的映射关系;
实际上数据在经过NAT路由器出去的时候不仅仅是把你的源ip替换掉而是路由器会维护一张映射表。我们之前标识一对请求连接用的是源ip源端口目的ip和目的端口这一组信息在自己的内网当中一定是具有唯一性的。说白了就是路由器在做转化的时候除了把源ip替换过去之外还要给我建立映射关系。实际上在做NAT的时候端口号也有可能变化。
转化实例 NAPT
那么问题来了, 如果局域网内, 有多个主机都访问同一个外网服务器, 那么对于服务器返回的数据中, 目的IP都是相同的. 那么NAT路由器如何判定将这个数据包转发给哪个局域网的主机? 这时候NAPT来解决这个问题了. 使用IPport来建立这个关联关系 因为双方都具有唯一性所以路由表会把这一对具有唯一性的值建立映射关系。所以报文在出去的时候我们的路由表中就会维护这次请求建立的映射关系因为彼此都有唯一性所以可以做到互为键值而且这些键值本身就有通信细节所以当一个报文回来时我们再把该报文的目的ip和目的端口在替换成转化表当中曾经的ip和端口这样的话路由器就可以把报文定向的交给客户端了。 这种关联关系也是由NAT路由器自动维护的. 例如在TCP的情况下, 建立连接时, 就会生成这个表项; 在断开连接后, 就会删除这个表项 eg:现在ip不足路由器功能扩展使用port的场景最多的就是映射了。路由器有很多端口目的就是为了进行映射可以理解成这些端口都是绑定的路由器的同一个服务。所以对我们来讲我们无数次出去的时候就可能在路上建立各种各样的NAT映射关系回来的时候就是不断的查这些NAT转化表的过程其中这些表结构的维护数据的维护量一定很大所以路上的路由器一定是运营商的路由器要求功率比较大家用路由器就只需要维护你家里的那几台设备的路由器就可以了。
转化实例 NAT为什么能延缓ip地址不足呢
因为有NAT的存在所有的家用路由器都可以维护NAT映射关系当你在进行外网请求的时候NAT路由器帮你建立映射关系帮你请求请求之后把结果给你然后在反查NAT表交互给用户。所以我们就可以做到经过家用路由器给我们构建出来的一个虚拟的子网就可以让所有的局域网内的ip地址都是一样的。以前入网的主机都需要公网现在不需要了直接用私网ip中间路由器就可以帮我们做到映射换句话说这些公网ip就只可以在公网中使用一般是都是企业运营商去用包括你自己的云服务器你扮演的就是企业的角色你就有公网ip除此之外就都是私网ip。
如果客户端A从来没有访问过服务器服务器能否访问客户端A吗
不行。因为客户端是个私有ip所以服务器想反向的访问是不可能的所以服务器最多能访问家用路由器但是家用路由器这个NAT没有映射表因为A从来没访问过服务器映射关系不存在服务器就访问不了。这样的话也变向的保护了内网的主机。所以你自己的机器别人想通过外网访问你是比较困难的。客户端A能出去就是因为服务器的ip地址是全网内唯一的所以你才可以访问。
浅谈虚拟机的网络连接模式 一些虚拟机在特定的场合下就会告诉你网络的连接模式有一种是桥接模式有一种是NAT。
你的计算机是windows的你在内部又装了虚拟机就相当于在你的计算机里又跑了一个计算机但是网卡只有一个现在虚拟机要上网就有两种方式
一、NAT模式
我的虚拟机把你的windows这台机器当成一个大的路由器这个大路由器给我的虚拟机构建一个子网我虚拟机的所有请求都通过你的windows机器向外网发起请求。
说人话把windows当成路由器就需要windows帮助虚拟机维护NAT转化表所有所有的报文在其他人看来好像都是你这个windows机器在发起请求。这就叫做NAT。
这种模式就是让虚拟系统借助NAT(网络地址转换)功能通过宿主机器所在的网络来访问公网。也就是说使用NAT模式能够实现在虚拟的系统里面直接访问互联网。NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCPserver提供的无法进行手工改动因此虚拟系统也就无法和本局域网中的其它真实主机进行通讯。采用NAT模式最大的优势是虚拟系统接入互联网很容易。仅仅需要宿主机器能访问互联网不需配置IP地址子网掩码网关。可是DNS地址还是要依据实际情况配的。
二、桥接模式
让windows直接联网让虚拟机也直接联网就相当于我们两个共用网卡但是我们两个的地位是对等的也就是虚拟机就是局域网中的某台主机这就是桥接。
在桥接模式下虚拟机虚拟出来的操作系统就像是局域网中一台独立的主机它能够访问网内任何一台机器。
在桥接模式下必须手动为虚拟系统配置IP地址、子网掩码并且还要和宿主机器处于同一网段这样虚拟系统才能和主机进行通信。
配置好网关和DNS的地址后。才能实现通过局域网的网关或路由器访问互联网。
桥接模式虚机和物理主机可通信可与外网通信。 NAT说白了就是维护一个内网到外网外网到内网的一个关系他俩互为键值所以就可以直接出去进来进来出去。
NAT技术的缺陷
由于NAT依赖这个转换表, 所以有诸多限制: 无法从NAT外部向内部服务器建立连接; 装换表的生成和销毁都需要额外开销都需要花内存; 通信过程中一旦NAT设备异常, 即使存在热备, 所有的TCP连接也都会断开;
相关拓展: NAT穿越NAT和代理服务器 路由器往往都具备NAT设备的功能, 通过NAT设备进行中转, 完成子网设备和其他子网设备的通信过程 代理服务器看起来和NAT设备有一点像. 客户端向代理服务器发送请求, 代理服务器将请求转发给真正要请求的服务器; 服务器返回结果后, 代理服务器又把结果回传给客户端. 代理服务器 正向代理 之前我们都说的是客户端可以直接访问服务器事实上确实是直接可以访问的但是有时候确不是这样的。 就比如校园网客户端访问的时候并不是直接访问服务器的而是访问代理服务器的这个代理服务器不是路由器它就和服务器一样就是一台服务器。所有同学上网的请求都是先发送到代理服务器代理服务器收到你们的请求在转发给服务器。对我们来讲学生发送请求都是在内网中做的。站在客户端你一定知道你访问的服务器是哪个(就比如你访问的是百度)。但是在服务器端只知道有一台机器(代理服务器)来访问我了并不知道是谁访问的我。 为什么要有个代理服务器呢 1.便于对同学的身份做认证比如我们的校园网是个大WiFi只要连上我们校园网的人就能够直接使用这就是浪费资源。所以我们连上校园网之后还要有自己的账号和密码只有账号密码输对了你才有资格上校园网这就是对你的学生身份做认证。 2.如果你的代理服务器侦测到有个电影最近被大家访问好多次了于是代理服务器就可以把这个电影做保存保存之后如果再有人其他人访问这个电影就不用再去访问外网了而是之际从内网中拿到所以第二个优点就是加速内网访问服务。 3.如果没有代理服务器我们也是有内网的就变成了你们直接访问外网这样就相当于我们的校园网对外几乎是一个半公开状态的网络这样的话就很容易出现问题。就好比今天有代理服务器的存在如果你想上网的话服务器看来就只有这个代理服务器这一台机器存在。如果没有代理服务器小白上网的话就有可能把小白暴露出去了如果服务器是个非法的其中服务器直接面对的就是啥也不懂的小白了所以这些小白很容易受到攻击。所以代理服务器可以对访问内网的请求进行筛查。相当于如果是客户端发起请求服务端的响应还好如果是服务器的主动请求就要进行筛查所以一般在代理服务器中我们就可以部署上很多的安全策略代理服务器相当于保护内网的角色。 这种代理就称之为正向代理。正向代理就是在客户端内网当中搞出来的一个正向代理。实际上也不一定是内网这只是举个例子学校中可能是1号楼是一个网2号楼是一个网...大家所有的请求都可以通过这个代理服务器向外网发起请求。代理服务器有各种构成方式无路如何都是靠近客户端的。 反向代理 假设公司有100台服务器有100万人来访问企业不可能把自己内网中的机器全部暴露出去因为很容易受到攻击。 当用户访问时候访问的不仅仅是服务器而是也有个代理服务器将来所有的请求都是先请求代理服务器但是我这个代理服务器不给你做任何的业务处理仅仅做业务转发根据后端每一台机器的负载情况进行业务转发。 我们如果把所有的请求都打在一台机器上肯定是不行的因为就会造成旱的旱死涝的涝死而且用户体验也是极差的。最理想的情况就是较为均衡的将请求打散到每一台服务器上这种通过代理服务器做到的策略就是负载均衡。 服务器收到请求后要么就可以把响应发给代理服务器通过代理服务器发给客户端也可以直接响应回客户端不经过代理服务器。端口我们是有in端口和out端口像这种方式我们就可以把服务器的out端口打开in端口关闭也就是客户端不能直接像服务器发消息但是服务器可以向客户端发消息。这样的话代理服务器主要用来做公司内部的入网许可请求连接的有效甄别还有负载均衡。 反向代理的优点负载均衡安全 那么NAT和代理服务器的区别有哪些呢?
从应用上讲, NAT设备是网络基础设备之一, 解决的是IP不足的问题. 代理服务器则是更贴近具体应用, 比如通过代理服务器进行翻墙, 另外像迅游这样的加速器, 也是使用代理服务器. 从底层实现上讲, NAT是工作在网络层, 直接对IP地址进行替换. 代理服务器往往工作在应用层. 从使用范围上讲, NAT一般在局域网的出口部署, 代理服务器可以在局域网做, 也可以在广域网做, 也可以跨网.
翻墙的原理
我们访问不了外网的原因就是因为有墙。
背景
当你的机器发起请求一定是经过网络运营商一定是最先收到你的请求的因为你必须走它基础设施就是运营商搭建的而且你的网费流量费都是交给人家的。然后运营商将你的请求转发给服务器(比如说QQ)QQ在反向的给运营商做相关的转发把数据交给你。所有的请求都要经过运营商运营商在这个环节里起的就是一个霸主的地位。如果你的报文没有经过任何加密的话你所有的报文都是裸的实际上报文在转发的时候就是在选择子网的过程子网是提前建设好的所有的报文在任何一个环节当中一定是在某个时刻处于一个网段的也就是一个局域网也就是一定处于局域网通信的过程中所以我就可以在报文发送的路上以中间人的方式进行抓取报文(如果报文没加密)。换句话说你请求的是QQ运营商是能得知的。
我们一般访问服务器的时候用的是HTTPS协议你也一定是要有url的比如你访问某个网站你通过url向对方发起请求就给他发送http报文一定包含了你想要请求的目标网址。对我们来讲运营商是可以得知你请求的很多信息的运营商内部具有一定的白名单策略只要你访问的是国内的一些公司就正常给你转发但是比如你访问谷歌我们就直接被拦截了。 在我们看来是完成了域名解析的然后就向这个ip发起请求ip地址是划分区域的如果你访问了这样的ip的话运营商就识别到这个ip是国外的ip是处在黑名单中的一个ip就不让你建立连接。即便是你建立了连接后面你再去访问谷歌的相关资源也访问不到运营商可能在内部对你的内容做处理。
原理
我们想要去外网就得做这两件事情
1.我们如何做能骗过运营商呢告诉运营商你访问的是一个合法的网站。2.将来你骗过他以后你怎么回来呢你回来的时候也是需要骗过运营商再把信息转给你。
首先你得具有一台可以访问外网的机器这台机器
1.是能被我的内网所访问的2.可以去访问对应的外网。
这样的机器是存在的有一些云服务器就是这样的。比如我要访问香港的机器香港是国内的运营商照样需要把报文做转发香港是可以访问国外的所以香港的机器就可以做这样的事情
第二步我在这台机器内部部署代理服务最常见的代理服务比如说Nginx. 什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件IMAP/POP3代理服务器在BSD-like 协议下发行。其特点是占有内存少并发能力强事实上nginx的并发能力确实在同类型的网页服务器中表现较好中国大陆使用nginx网站用户有百度、京东、新浪、网易、腾讯、淘宝等。 你想要进行上外网的时候你自己一定要安装一种客户端这种客户端的作用和Fiddler一样。以前你的浏览器是直接访问运营商然后访问公网的现在你的这个客户端软件就相当于把你的浏览器劫持了然后你的所有请求就由这个软件做处理然后这个软件带你去请求。 比如你今天访问谷歌这个请求不是直接从你的机器发送到运营商而是先被你这个客户端获取到然后把你访问谷歌的这个请求当做正文形成一个新的访问代理服务器的请求。所以此时就把你的请求交给运营商运营商发现你此时访问的是这个代理服务器没有问题。当然运营商也是会考虑这样的问题的运营商会对你文本中的内容做相关的分析分析你信息中有没有访问外网的信息比如扫描出来你的正文部分还是包含了谷歌运营商照样给你丢弃这个请求。所以你的客户端不仅仅是把你的请求包裹到一个新的请求中而且还要进行加密(最主要的目的就是不让运营商知道我是谁)。所以此时运营商就交给了代理服务器此时代理服务器就把访问我的请求直接去掉拿出内部真正的东西进行解密解密之后就得到了访问谷歌的请求此时你的代理服务器就可以直接访问谷歌谷歌就把响应返回代理服务器然后代理服务器就把谷歌的响应作为一个报文加密封装起来重新形成一个新的响应此时在返回给运营商。运营商检测不出来就返回给你的客户端客户端收到后就去掉报头把正文解密出来然后把正文的http交给你的浏览器剩下的就是你的浏览器对谷歌的http做报头处理正文渲染然后你就拿到了对应的网页。 所以如果你自己要上网你要有一台能够访问外网的服务器然后编写一个客户端他俩都要有加密和解密的功能。 我们一般在云服务器上是没有办法绑定自己的公网ip的为什么呢 博主的云服务器是有一个公网ip和内网ip的这是通过腾讯云的后台查看的 单单在博主的机器上只能查到内网ip 实际上你自己的请求是经过反向代理服务器反向代理再转发给服务器所以你有时候看到给你分配的公网ip完全不是你这台机器的ip这个公网ip有可能就是干脆模拟出来的。 当你请求的时候请求的是代理服务器代理服务器就会把你的请求转发到你的服务器上所以你自己在你的机器上查的时候只能查到你的私有ip你在云服务器厂商那里你可以看到公网ip是啥和私网ip是啥。 实际上所有访问公网的这个请求最终相当于内部建立了一张映射表将来所有人想访问特定区域的ip地址都会发到代理服务器上内部做映射帮你找到你的机器所以通过反向代理找到你的机器最后让你使用你的机器所以你所看到的公网ip并不是真正的ip这是腾讯给你模拟出来的ip所以你的机器里并不存在这样的公网ip地址你也就没办法绑定所以这样就是为什么在线上生产环境当中我们必须得保证不要绑定公网ip因为这个公网ip本身就不存在此时建议绑定0这样就相当于从任何地方来的在主机上任何的报文情况我都能收到线上生产环境全部建议用0。 为什么socket通信时服务端不能绑定云服务器的公网ip及为什么要绑定INADDR_ANY
当然你在socket通信的时候是可以绑定你的云服务器的私网ip的如果是在同一局域网客户端就可以通过访问你云服务器的私网ip进行通信(就是局域网通信)但是我们是在不同的局域网客户端光访问你的私网ip是无法进行通信的所以客户端就必须知道你的公网ip。但是你的云服务器实际上并没有公网ip这个公网ip是腾讯给你这台云服务器模拟出来的并且腾讯将这个公网ip和云服务器自己的私网ip做了映射只要访问这个公网ip最终就是访问到你的云服务器上了。
可是对于云服务器来讲我们绑定的时候也不能绑定这个公网ip因为拥有这个公网ip的很可能是一个入口路由器你写的全部服务都在你的云服务器上而拥有这个公网ip的路由器并不提供服务所以我们就不能绑定这个公网ip你可以绑定的就是你的服务器的私网ip这样的话只要客户端访问这个公网ip就能直接映射到你的云服务器上使用云服务器上缩写的服务。
但是我们一般也不进行绑定云服务器的私网ip我们一般绑定的都是INADDR_ANY。
INADDR_ANY 转换过来就是0.0.0.0泛指本机的意思也就是表示本机的所有IP因为有些机子不止一块网卡多网卡的情况下这个就表示所有网卡ip地址的意思。 比如一台电脑有3块网卡分别连接三个网络那么这台电脑就有3个ip地址了如果某个应用程序需要监听某个端口那他要监听哪个网卡地址的端口呢
如果绑定某个具体的ip地址你只能监听你所设置的ip地址所在的网卡的端口其它两块网卡无法监听端口如果我需要三个网卡都监听那就需要绑定3个ip也就等于需要管理3个套接字进行数据交换这样岂不是很繁琐
所以出现INADDR_ANY你只需绑定INADDR_ANY管理一个套接字就行不管数据是从哪个网卡过来的只要是绑定的端口号过来的数据都可以接收到。