无题
3.2.2 字符填充的首尾定界符法
3.2.4 违规编码法
3.3 差错控制
3.3.1 检错编码
3.4 流量控制与可靠传输机制
3.4.1 滑动窗口机制
发送窗口:在任意时刻,发送方都维持一组连续的允许发送的帧的序号。
- 发送窗口用来对发送方进行流量控制,而发送窗口的大小WT,代表在还未收到对方确认信息的情况下发送方最多还可以发送多少个数据帧。
接收窗口:接收方也维持一组连续的允许接收帧的序号。
- 接收窗口是为了控制可以接收哪些数据帧和不可以接收哪些帧。
- 在接收方,只有收到的数据帧的序号落入接收窗口内时,才允许将该数据帧收下。
- 若接收到的数据帧落在接收窗口之外,则一律将其丢弃。
滑动窗口特性:
- 只有接收窗口向前滑动(同时接收方发送了确认帧)时,发送窗口才有可能(只有发送方收到确认帧后才一定)向前滑动。
- 从滑动窗口的概念看,停止-等待协议、后退N帧协议和选择重传协议只在发送窗口大小与接收窗口大小上有所差别:
- 停止-等待协议:发送窗口大小=1,接收窗口大小=1。
- 后退N帧协议:发送窗口大小>1,接收窗口大小=1。
- 选择重传协议:
- 接收窗口的大小为1时,可保证帧的有序接收。
- 数据链路层的滑动窗口协议中,窗口的大小在传输过程中是固定的(注意与第5章传输层的滑动窗口协议的区别)。
可靠传输机制:
- 确认:确认是一种无数据的控制帧,这种控制帧使得接收方可以让发送方知道哪些内容被正确接收。有些情况下为了提高传输效率,将确认捎带在一个回复帧中,称为捎带确认。
- 超时重传:超时重传是指发送方在发送某个数据帧后就开启一个计时器,在一定时间内如果没有得到发送的数据帧的确认帧,那么就重新发送该数据帧,直到发送成功为止。
- 自动重传请求(Automatic Repeat reQuest, ARQ):通过接收方请求发送方重传出错的数据帧来恢复出错的帧,是通信中用于处理信道所带来差错的方法之一。传统ARQ有三种:停止-等待(Stop-and-Wait) ARQ、 后退 N帧(Go-Back-N)ARQ 和选择性重传(Selective Repeat)ARQ。
在数据链路层中流量控制机制和可靠传输机制是交织在一起的,都由滑动窗口机制解决。
3.4.2 单帧滑动窗口与停止-等待协议
- 定义
在停止-等待协议中,源站每发送完一个帧就停止发送,等待对方的确认,在收到确认后再发送下一个帧。
- 有差错情况
超时计时器:每次发送一个帧就启动一个计时,超时计时器设置的重传时间应当比帧传输的平均RTT更长。
- 发完一个帧后,必须保留它的副本。
- 发送的帧交替地用0和1来标识,确认帧分别用ACK0和ACK1来表示,收到的确认帧有误时,重传已发送的帧。
发送失败的三种情况:
- 数据帧丢失或检测到帧出错:数据帧丢失时,或者接收方检测到数据帧有错,不返回ACK,超时重传。
- ACK丢失:接收方接收到数据帧,返回ACK时丢失,发送方超时重传。
- ACK迟到:接收方收到数据帧后,返回ACK0,但是ACK到达时间超过重传时间,发送方重新发送数据,接收到ACK0时丢失,因为此刻等待ACK1的接收。
- 性能分析
由于要花费大量时间等待ack确认,信道利用率太低。
信道利用率 U = T D T D + R T T + T A 信道利用率U=\frac {T_D} {T_D+RTT+T_A} 信道利用率U=TD+RTT+TATD
3.4.3 多帧滑动窗口与后退N帧协议(GBN)
在后退N帧式ARQ中,发送方无须在收到上一个帧的ACK后才能开始发送下一帧,而是可以连续发送帧。
发送窗口大小>1,接收窗口大小=1。
发送方
- 上层的调用:上层要发送数据时,发送方先检查发送窗口是否己满,如果未满,则产生一个带序号的帧并将其发送;如果窗口已满发送方可以缓存这些数据,窗口不满时再发送帧。
- 收到了一个ACK:GBN协议中,对n号帧的确认采用累积确认的方式,标明接收方已经收到n号帧和它之前的全部帧。
- 超时事件:协议的名字为后退N帧/回退N帧,来源于出现丢失和时延过长帧时发送方的行为。就像在停等协议中一样,定时器将再次用于恢复数据帧或确认帧的丢失。如果出现超时,发送方重传所有己发送但未被确认的帧。
接收方
如果正确按序收到n号帧,那么接收方为n帧发送一个ACK,并将该帧中的数据部分交付给上层。
其余情况都丢弃帧,并为最近按序接收的帧重新发送ACK。
接收方无需缓存任何失序帧,只需要维护一个信息:expectedseqnum(下一个按序接收的帧序号)。
窗口大小
接收窗口为1,可以保证按序接收数据帧。
若采用n比特对帧编号,则其发送窗口的尺寸WT应满足 1 < W T ≤ 2 n − 1 1<W_T≤2^n-1 1<WT≤2n−1。若发送窗口大于 2 n − 1 2^n-1 2n−1,则会造成接收方无法分辨新帧和旧帧。
性能分析
- 优点:因连续发送数据帧而提高了信道利用率
- 缺点:在重传时必须把原来已经正确传送的数据帧重传,是传送效率降低。
信道的传输质量很差导致误码率较大时,后退N帧协议不一定优于停止-等待协议。
3.4.4 多帧滑动窗口与选择重传协议(SR)
为解决GBN会重传正确传送的帧,设法只重传出现差错和超时的数据帧,这需要加大接收窗口,因此提出了选择重传协议。
发送窗口大小>1,接收窗口大小>1。
发送方
上层的调用:从上层收到数据后,发送方检查下一个可用于该帧的序号,如果序号位于发送窗口内,则发送数据帧;否则就像GBN一样,要么将数据缓存,要么返回给上层之后再传输。
收到了一个ACK:如果收到ACK,假如该帧序号在窗口内,则SR发送方将那个被确认的帧标记为已接收。
如果该帧序号是窗口的下界(最左边第一个窗口对应的序号),则窗口向前移动到具有最小序号的未确认帧处。如果窗口移动了并且有序号在窗口内的未发送帧,则发送这些帧。
超时事件:每个帧都有自己的定时器,一个超时事件发生后只重传一个帧。
接收方
- 来者不拒(窗口内的帧):SR接收方将确认一个正确接收的帧而不管其是否按序。失序的帧将被缓存,并返回给发送方一个该帧的确认帧【收谁确认谁】,直到所有帧(即序号更小的帧)皆被收到为止,这时才可以将一批帧按序交付给上层,然后向前移动滑动窗口。
- 如果收到了**窗口序号外(小于窗口下界)**的帧,就返回一个ACK。其他情况,就忽略该帧。
窗口大小
发送窗口尺寸WT和接收窗口尺寸WR都大于1,一次可接收发送多个帧。
WT = WR时最好,若采用n比特对帧编号,则需满足 W T m a x = W R m a x = 2 n − 1 W_{Tmax}=W_{Rmax}=2^{n-1} WTmax=WRmax=2n−1,且 W T + W R ≤ 2 n W_T+W_R≤2^n WT+WR≤2n。
如果不满足窗口大小大于序号范围一半,当一个或多个确认帧丢失时,发送方就会超时重传之前的数据帧,但接收方无法分辨是新的数据帧还是重传的数据帧。
性能分析
信道利用率:也称信道效率,是对发送方而言的,是指发送方在一个发送周期的时间内,有效地发送数据所需要的时间占整个发送周期的比率。发送方从开始发送数据到收到第一个确认帧为止,称为一个发送周期。
设一个发送周期为T,发送周期内共发送L比特的数据,发送方数据传输率为C,则发送方发送有效数据时间为 L / C L/C L/C,信道利用率为 ( L / C ) / T (L/C)/T (L/C)/T。
信道吞吐率: 信道吞吐率 = 信道利用率 × 发送方发送速率 信道吞吐率=信道利用率×发送方发送速率 信道吞吐率=信道利用率×发送方发送速率
最小帧长: 最小帧长 = 2 × 数据传输速率 × 总线传播时延 最小帧长=2×数据传输速率×总线传播时延 最小帧长=2×数据传输速率×总线传播时延
3.5 介质访问控制
介质访问控制的内容就是,采取一定的措施,使得两对节点之间的通信不会发生互相干扰的情况。用来决定广播信道中信道分配的协议属于数据链路层的一个子层,称为介质访问控制(Medium Access Control, MAC)子层。
3.5.1 信道划分介质访问控制
信道划分介质访问控制是将使用介质的每个设备与来自同一信道上的其他设备的通信隔离开,把时域和频域资源合理地分配给网络上的设备。通常采用多路复用技术,把多个输入通道的信息整合到一个复用通道中,在接收端把收到的信息分离。
频分多路复用(FDM)
用户在相同时间占用不同频率带宽资源。每个子信道分配的带宽可不相同,但它们的总和必须不超过信道的总带宽。在实际应用中为了防止子信道之间的干扰,相邻信道之间需要加入“保护频带”。共享时间。
时分多路复用(TDM)
每一个时分复用的用户在每一个TDM帧占用固定序号的时隙,所有用户轮流占用信道。
不会发生碰撞,TDM帧是在物理层传送的比特流所划分的帧,标志一个周期。共享空间。
统计时分多路复用(STDM)
每一个STDM帧中的时隙数小于连接在集中器上的用户数。各用户有了数据就随时发往集中器的输入缓存,然后集中器按顺序依次扫描输入缓存,把缓存中的输入数据放入STDM帧中,一个STDM帧满了就发出。STDM帧不是固定分配时隙,而是按需动态分配时隙。
波分多路复用(WDM)
波分多路复用就是光的频分多路复用,在一根光纤中传输多种不同波长(频率)的光信号,由于波长(频率)不同,所以各路光信号互不干扰,最后再用波长分解复用器将各路波长分解出来。
码分多路复用(CDM)
码分多路复用是靠不同的编码来区分各路原始信号的一种复用方式。既共享信道的频率,又共享时间。
码分多址(CDMA):每个比特时间再划分成m个短的时间槽,称为码片(Chip),通常m的值是64或128。每个站点指派m位码片序列,发送1时发原码,0时发反码。各个站点码片序列相互正交。
CDMA原理:
假如站点A的码片序列被指派为00011011,则A站发送00011011就表示发送比特1,发送11100100就表示发送比特0。为了方便,按惯例将码片中的0写为-1,将1写为+1,因此A站的码片序列是-1-1-1+1+1-1+1+1。
令向量S表示A站的码片向量,令T表示B站的码片向量。两个不同站的码片序列正交,即向量S和T的规格化内积(Inner Product)为0:
S ⋅ T = 1 m ∑ i = 1 m S i T i = 0 S·T=\frac{1}{m}\sum_{i=1}^{m} {S_iT_i}=0 S⋅T=m1i=1∑mSiTi=0
任何一个码片向量和该码片向量自身的规格化内积都是1,任何一个码片向量和该码片反码的向量的规格化内积是-1例:A站码片00011011、B站码片00101110;此时A、B站向量相乘内积为0。
当A站向C站发送数据1时,就发送了向量(-1-1-1+1+1-1+1+1)。
当B站向C站发送数据0时,就发送了向量(+1+1-1+1-1-1-1+1)。
两个向量到了公共信道上就进行叠加,实际上就是线性相加,得到S+T=(0 0 -2 2 0 -2 0 2)
到达C站后,想获得A站数据,就与A站码片S内积化, S ⋅ ( S + T ) = 1 S·(S+T)=1 S⋅(S+T)=1,所以A站数据是1;同理, T ⋅ ( S + T ) = − 1 T·(S+T)=-1 T⋅(S+T)=−1,所以B站发过来的向量是个反码向量,代表0。
3.5.2 随机访问介质访问控制
随机访问介质中使用争用型协议 ,胜利者通过争用获得信道,从而获得信息的发送权。将广播信道转化为点到点信道。信道并非在用户通信时固定分配给用户
ALOHA协议
纯ALOHA协议
- 思想:不监听信道,不按时间槽发送,随机重发。想发就发
- 冲突检测:如果发生冲突,接收方在就会检测出差错,然后不予确认,发送方在一定时间内收不到就判断发生冲突。
- 冲突解决:超时后等一随机时间再重传。
时隙ALOHA协议
- 思想:把时间分成若干个相同的时间片,所有用户在时间片开始时刻同步接入网络信道,若发生冲突,则必须等到下一个时间片开始时刻再发送。控制想发就发的随意性。
- 吞吐量是纯ALOHA协议的两倍。
CSMA协议
载波监听多路访问(CSMA)指的是每个站点在发送前都先监听一下共用信道,发现信道空闲后再发送。
监听:当几个站同时在总线上发送数据时,总线上的信号电压摆动值将会增大(互相叠加)。当一个站检测到的信号电压摆动值超过一定门限值时,就认为总线上至少有两个站同时在发送数据,表明产生了碰撞,即发生了冲突。
1-坚持 CSMA
坚持指的是对于监听信道忙之后的坚持。
- 思想:如果一个主机要发送消息,那么它先监听信道。空闲则直接传输,不必等待。忙则一直监听,直到空闲马上传输。如果有冲突(一段时间内未收到肯定回复),则等待一个随机长的时间再监听,重复上述过程。
- 优点:只要媒体空闲,站点就马上发送,避免了媒体利用率的损失。
- 缺点:假如有两个或两个以上的站点有数据要发送,冲突就不可避免。
非坚持CSMA
非坚持指的是对于监听信道忙之后就不继续监听。
- 思想:如果一个主机要发送消息,那么它先监听信道。空闲则直接传输,不必等待。忙则等待一个随机的时间之后再进行监听。
- 优点:采用随机的重发延迟时间可以减少冲突发生的可能性。
- 缺点:可能存在大家都在延迟等待过程中,使得媒体仍可能处于空闲状态,媒体使用率降低。
p-坚持 CSMA
P坚持指的是对于监听信道空闲的处理。
- 思想:如果一个主机要发送消息,那么它先监听信道。空闲则以p概率直接传输,不必等待;概率1-p等待到下一个时间槽再传输。忙则持续监听直到信道空闲再以p概率发送。若冲突则等到下一个时间槽开始再监听并重复上述过程。
- 优点:既能像非坚持算法那样减少冲突,又能像1-坚持算法那样减少媒体空闲时间的这种方案。
- 缺点:发生冲突后还是要坚持把数据帧发送完,造成了浪费。
信道状态 1-坚持 非坚持 p-坚持 空闲 立即发送数据 立即发送数据 以概率p发送数据 以概率1-p推迟到下一个时隙 忙 继续坚持监听 放弃监听,等待随机的时间后再监听 持续监听,直至信道空闲 CSMA/CD 协议
载波监听多路访问/碰撞检测(CSMA/CD)协议是CSMA的改进方案,适用于总线形网络或半双工网络。
碰撞检测就是边发送边监听,如果 监听到了碰撞,则立即停止数据发送,等待一段随机时间后,重新开始尝试发送数据。
工作流程:先听后发,边听边发,冲突停发,随机重发
1)适配器从网络中获得分组,封装成以太帧,缓存等待发送
2)适配器侦听信道,空闲则发送,忙则持续监听,直到空闲发送
3)发送过程中持续检测信道,若检测到碰撞,停止发连并发送一个拥塞信号
4)中止发送后,执行指数退避法确定重传时机
争议期:两端往返传播时延。只要经过2τ(传播时延)时间还没有检测到碰撞,就能肯定这次发送不会发生碰撞。
最小帧长=总线传播时延×数据传输速率×2
以太网规定取51.2μs为争用期的长度。对于10Mb/s的以太网,在争用期内可发送512bit,即64B。
如果只发送小于64B的帧,如40B的帧,那么需要在MAC子层中于数据字段的后面加入一个整数字节的填充字段,以保证以太网的MAC帧的长度不小于64B。
截断二进制指数规避算法:
1.确定基本退避(推迟)时间为争用期2τ。
2.定义参数k,它等于重传次数,但k不超过10,即k=min[重传次数,10]。
3.从离散的整数集合[0,1…2k-1]中随机取出一个数r, 重传所需要退避的时间就是r倍基本退避时间,即2rτ。
4.当重传达16次仍不能成功时,说明网络太拥挤,认为此帧永远无法正确发出,抛弃此帧并向高层报错。
使用截断二进制指数退避算法可使重传需要推迟的平均时间随重传次数的增大而增大(这也称动态退避),因而能降低发生碰撞的概率,有利于整个系统的稳定。
CSMA/CA协议
CSMA/CD协议无法用于无线局域网,因为其无法做到360°全面检测碰撞。会出现隐蔽站问题。
隐蔽站:当A和C都检测不到信号,认为信道空闲时,同时向终端B发送数据帧,就会导致冲突。
载波监听多路访问/碰撞避免(CSMA/CA):协议的设计要尽量降低碰撞发生的概率。
工作原理:
1)发送数据前,先检测信道是否空闲。
2)空闲则发出RTS(request to send),RTS包括发射端的地址、接收端的地址、下一份数据将持续发送的时间等信息;信道忙则等待。
3)接收端收到RTS后,将响应CTS(clear to send)。CTS帧 ①给源站明确的发送许可;②指示其他站点在预约期内不要发送。
4)发送端收到CTS后,开始发送数据帧(同时预约信道:发送方告知其他站点自己要传多久数据)。
5)接收端收到数据帧后,将用循环冗余码CRC来检验数据是否正确,正确则响应ACK帧。
6)发送方收到ACK就可以进行下一个数据帧的发送,若没有则一直重传至规定重发次数为止(采用二进制指数退避:算法来确定随机的推迟时间)。帧间间隔(IFS):为了尽量避免碰撞,802.11规定,所有的站完成发送后,必须再等待一段很短的时间(继续监听)才能发送下一帧。
1)SIFS(短IFS):最短的IFS,用来分隔属于一次对话的各帧,使用SIFS的帧类型有ACK帧、CTS帧、分片后的数据帧,以及所有回答AP探询的帧等。
2)PIFS(点协调IFS):中等长度的IFS,在PCF操作中使用。
3)DIFS(分布式协调IFS):最长的IFS,用于异步帧竞争访问的时延。CSMA/CD与CSMA/CA主要有如下区别:
1.传输介质不同:CSMA/CD用于总线式以太网【有线】,而CSMA/CA用于无线局域网【无线】。
2.载波检测方式不同:因传输介质不同,CSMA/CD与CSMA/CA的检测方式也不同。
CSMA/CD通过电缆中电压的变化来检测,当数据发生碰撞时,电缆中的电压就会随着发生变化;
而CSMA/CA采用能量检测(ED)、载波检测(CS)和能量载波混合检测三种检测信道空闲的方式。
3.CSMA/CD检测冲突,CSMA/CA避免冲突,二者出现冲突后都会进行有上限的重传。
3.5.3 轮询访问:令牌传递协议
在轮询访问中,用户不能随机地发送信息,而要通过一个集中控制的监控站,以循环方式轮询每个结点,再决定信道的分配。
令牌传递协议:每个结点都可以在一定的时间内(令牌持有时间)获得发送数据的权利,并不是无限制地持有令牌。主要用在令牌环局域网(物理星型拓扑,逻辑环形拓扑)。
令牌:一个特殊的MAC控制帧,它不包含信息,仅控制信道的使用,确保同一时刻只有一个站点独占信道。
传递过程:
1)网络空闲时,环路中只有令牌帧在循环传递
2)令牌传递到有数据要发送的站点时,该站点就修改令牌中的一个标志位,并在令牌中附加自己需要传输的数据,将令牌变成一个数据帧,然后将这个数据帧发送出去
3)数据帧沿着环路传输,接收到的站点一边转发数据,一边查看帧的目的地址。如果目的地址和自己的地址相同,那么接收站就复制该数据帧以便进一步处理。
4)数据帧沿着环路传输,直到到达该帧的源站点,源站点收到自己发出去的帧后便不再转发。同时,通过检验返回的帧来查看数据传输过程中是否出错,若有错则重传。
5)源站点传送完数据后,重新产生一个令牌,并传递给下一站点,以交出信道控制权。应用:采用令牌传送方式的网络常用于负载较重、通信量较大的网络中。
3.6 局域网
3.6.1 局域网的基本概念和体系结构
局域网(LAN)指在某一区域内由多台计算机互联成的计算机组,使用广播信道。
特点
- 覆盖的地理范围较小,只在一个相对独立的局部范围内联,如一座或集中的建筑群内。
- 使用专门铺设的传输介质(双绞线、同轴电缆)进行联网,数据传输速率高(10Mb/s~10Gb/s)。
- 通信延迟时间短,误码率低,可靠性较高。
- 各站为平等关系,共享传输信道。
- 多采用分布式控制和广播式通信,能进行广播和组播。
局域网拓扑结构
①星形结构;②环形结构;③总线形结构;④星形和总线形结合的复合型结构。
传输介质
局域网可以使用双绞线、铜缆和光纤等多种传输介质,其中双绞线为主流传输介质。
介质访问控制方法
主要有CSMA/CD、令牌总线和令牌环,其中前两种方法主要用于总线形局域网,令牌环主要用于环形局域网。
局域网拓扑
- 以太网(目前使用范围最广的局域网)。逻辑拓扑是总线形结构,物理拓扑是星形或拓展星形结构。
- 令牌环(Token Ring,IEEE802.5)。逻辑拓扑是环形结构,物理拓扑是星形结构。
- FDDI(光纤分布数字接口,EEE802.8)。逻辑拓扑是环形结构,物理拓扑是双环结构。
MAC子层和LLC子层
LLC子层:逻辑链路控制子层,负责识别网络层协议,然后对它们进行封装(给帧加序号)。LLC报头告诉数据链路层一旦帧被接收到时,应当对数据包做何处理。
主要功能:建立和释放数据链路层的逻辑连接、提供与高层的接口、差错控制、给帧加序号。与传输媒体无关。
MAC子层:介质访问控制子层,向上层屏蔽对物理层访问的各种差异,提供对物理层的统一访问接口。
主要功能包括:组帧和拆卸帧、比特传输差错检测、透明传输。
3.6.2 以太网与 IEEE 802.3
IEEE 802.3标准是一种基带总线形的局域网标准,它描述物理层和数据链路层的MAC子层的实现方法。
以太网逻辑上采用总线形拓扑结构,物理星型结构,以太网中的所有计算机共享同一条总线,信息以广播方式发送。为了保证数据通信的方便性和可靠性,以太网简化了通信流程并使用了 CSMA/CD方式对总线进行访问控制。
①采用**无连接的工作方式,不对发送的数据帧编号,也不要求接收方发送确认,即以太网尽最大努力交付数据,提供的是不可靠服务**,对于差错的纠正则由高层完成;
②发送的数据都使用曼彻斯特编码的信号,每个码元的中间出现一次电压转换,接收端利用这种电压转换方便地把位同步信号提取出来。
- 以太网的传输介质与网卡
以太网采用10BASE-T网络,采用的是无屏蔽双绞线(UTP),传输速率是10Mb/s。
参数 | 10BASE5 | 10BASE2 | 10BASE-T | 10BASE-FL |
---|---|---|---|---|
传输媒体 | 基带同轴电缆(粗缆) | 基带同轴电缆(细缆) | 非屏蔽双绞线 | 光纤对(850nm) |
编码 | 曼彻斯特编码 | 曼彻斯特编码 | 曼彻斯特编码 | 曼彻斯特编码 |
拓扑结构 | 总线形 | 总线形 | 星形 | 点对点 |
最大段长 | 500m | 185m | 100m | 2000m |
最多结点数目 | 100 | 30 | 2 | 2 |
计算机与外界局域网的连接是通过网卡(网络适配器,又称网络接口板/卡)实现的。网卡上装有处理器和存储器,是工作在数据链路层的网络组件。网卡和局域网的通信是通过电缆或双绞线以串行方式进行的,而网卡和计算机的通信则是通过计算机主板上的I/O总线以并行方式进行的。网卡的重要功能就是进行数据的串并转换。
MAC地址:介质访问控制(MAC)地址,每块网卡在出厂时的唯一代码,用于控制主机在网络上的数据通信。数据链路层设备(网桥、交换机等)都使用各个网卡的MAC地址。另外,网卡控制着主机对介质的访问,因此网卡也工作在物理层,因为它只关注比特,而不关注任何地址信息和高层协议信息。
以太网的MAC帧
MAC地址也称物理地址,MAC地址长6字节,一般用由连字符(或冒号)分 隔的12个十六进制数表示,如 06 − E A − 56 − 3 B − 4 F − 4 D 06-EA-56-3B-4F-4D 06−EA−56−3B−4F−4D。高24位为厂商代码,低24位为厂商自行分配 的网卡序列号。
以太网MAC帧格式有两种标准:DIX Ethernet V2标准(即以太网V2标准)和IEEE 802.3 标准。这里先介绍最常用的以太网V2的MAC帧格式,如图所示。
- 前导码:使接收端与发送端时钟同步。在帧前面插入的8字节可再分为两个字段:第一个字段共7字节,是前同步码,用来快速实现MAC帧的比特同步;第二个字段是帧开始定界符,表示后面的信息就是MAC帧。
- 地址:通常使用6字节(48bit)地址(MAC地址)。
- 类型:2字节,指出数据域中携带的数据应交给哪个协议实体处理。
- 数据:46
1500字节,包含高层的协议消息。由于CSMA/CD算法的限制,以太网帧必须满足最小长度要求64字节,数据较少时必须加以填充(046字节)。
注意:46是怎么来的?由CSMA/CD可知以太网帧的最短顿长为64B,而MAC帧的首部和尾部的长度为18字节,所以数据字段最短为64-18=46字节。最大的1500字节是规定的。
- 填充:0~46字节,当帧长太短时填充帧,使之达到64字节的最小长度。
- 校验码(FCS):4字节,校验范围从目的地址段到数据段的末尾,算法采用32位循环冗余码(CRC),不但需要检验MAC帧的数据部分,还要检验目的地址、源地址和类型字段,但不校验前导码。
802.3帧格式与DIX以太帧格式的不同之处在于用长度域替代了 DIX帧中的类型域,指出数据域的长度。
高速以太网
速率≥100Mb/s的以太网称为高速以太网。
100BASE-T 以太网
在双绞线上传送100Mb/s基带信号的星型拓扑以太网,仍使用IEEE802.3的CSMA/CD协议。
支持全双工和半双工,可在全双工方式下工作而无冲突。
吉比特以太网
在光纤或双绞线上传送1Gb/s信号。
支持全双工和半双工,可在全双工方式下工作而无冲突。
10吉比特以太网
10吉比特以太网在光纤上传送10Gb/s信号。
只支持全双工,无争用问题。
3.6.3 IEEE 802.11无线局域网
无线局域网的组成
1)有固定基础设施无线局域网
802.11使用星形拓扑,其中心称为接入点(Access Point, AP),在MAC层使用CSMA/CA协议。使用802.11系列协议的局域网又称Wi-Fi。
无线局域网的最小构件是基本服务集BSS (Basic Service Set, BSS)。一个基本服务集包括一个接入点和若干移动站。各站在本BSS内之间的通信,或与本BSS外部站的通 信,都必须通过本BSS的AP。
AP就是基本服务集中的基站(base station)。安装AP时,必须为该AP分配一个不超过32字节的服务集标识符(Service Set IDentifier, SSID)和一个信道。SSID是指使用该AP的无线局域网的名字。
一个基本服务集覆盖的地理范围称为一个基本服务区(Basic Service Area,BSA),无线局域网的基本服务区的范围直径一般不超过100m。
一个基本服务集可以是孤立的,也可通过AP连接到一个分配系统(Distribution System, DS),然后再连接到另一个基本服务集,就构成了一个扩展的服务集(Extended Service Set, ESS)。
ESS还可以通过一种称为 Portal (门户)的设备为无线用户提供到有线连接的以太网的接入。门户的作用相当于一个网桥。
移动站A如果要和另一个基本服务集中的移动站B通信,就必须经过两个接入点AP1和AP2,即A→AP1→AP2→B,注意AP,到AP2的通信是使用有线传输的。
2)无固定基础设施移动自组织网络
另一种无线局域网是无固定基础设施的无线局域网,又称自组网络(ad hoc network)。自组网络没有上述基本服务集中的AP,而是由一些平等状态的移动站相互通信组成的临时网络。各结点之间地位平等,中间结点都为转发结点,因此都具有路由器的功能。
802.11局域网的MAC帧
802.11帧共有三种类型,即数据帧、控制帧和管理帧。
数据帧
1)MAC首部,共30字节。帧的复杂性都在MAC首部。
2)帧主体,即帧的数据部分,不超过2312字节。它比以太网的最大长度长很多。
3)帧检验序列FCS是尾部,共4字节。
其中帧控制的去往AP和来自AP决定着地址内容,具体如下表所示。
去往AP | 来自AP | 地址1 | 地址2 | 地址3 | 地址4 |
---|---|---|---|---|---|
0 | 1 | 接收地址=目的地址 | 发送地址=AP地址 | 源地址 | —— |
1 | 0 | 接收地址=AP地址 | 发送地址=源地址 | 目的地址 | —— |
地址1是直接接收数据帧的结点地址,地址2是实际发送数据帧的结点地址。
3.6.4 VLAN基本概念与基本原理
虚拟局域网(VLAN)可以把一个较大的局域网分割成一些较小的与地理位置无关,逻辑上的VLAN,而每个VLAN是一个较小的广播域。VLAN分割了广播域。
802.3ac标准定义了支持VLAN的以太网帧格式的扩展,称为802.1Q帧。它在以太网帧中插入一个4字节的标识符(插入在源地址字段和类型字段之间),称为VLAN标签,用来指明发送该帧的计算机属于哪个虚拟局域网。
VLAN标签的前两个字节置为0x8100,表示这是一个802.1Q帧。在VLAN标签的后两个字节中,前4位没有用,后12位是该VLAN的标识符VID,它唯一标识了该802.1Q帧属于哪个VLAN。
VID的取值范围为04095,但0和4095都不用来表示VLAN,因此用于表示VLAN的有效VID取值范围为14094。12位的VID可识别4096个不同的VLAN。插入VID后,802.1Q帧的FCS必须重新计算。
IEEE 802.1Q帧是由交换机来处理的,而不是由用户主机来处理的。(即主机和交换机之间只交换普通的以太网帧)
如上图所示,交换机1连接了7台计算机,该局域网划分为两个虚拟局域网VLAN 10和VLAN 20,其中10和20是管理员分配的VID。主机不知道自己的VID,交换机知道所有的VID,主机与交换机用以太网帧交互。VLAN范围可以跨越交换机,交换机1与交换机2相连,并同时连接着两个VLAN。
这两个VLAN虽然都跨越了两个交换机,但各自都是一个广播域。
发送地址 | 目的地址 | 转发路径 |
---|---|---|
A | B | 交换机1查询目的地址接口,识别B属于本交换机管理的同VLAN设备 |
直接转发以太网帧 | ||
A | E | 交换机1查询目的地址接口,将帧转发到交换机2,并插入VLAN标签 |
交换机之间转发Q帧 | ||
A | C | 属于不同网络,需要通过路由器或者三层交换机完成转发 |
3.7 广域网
3.7.1 广域网基本概念
广域网通常是指覆盖范围很广(远超一个城市的范围)的长距离网络。广域网的通信子网主要使用分组交换技术。广域网由一些结点交换机(不是路由器)及连接这些交换机的链路组成。结点之间都是点到点连接,但为了提高网络的可靠性,通常一个结点交换机往往与多个结点交换机相连。
广域网不等于互联网。互联网可以连接不同类型的网络(既可以连接局域网,又可以连接广域网),通常使用路由器来连接。
广域网与局域网有相同有不同,相似点如下:
- 广域网和局域网都是互联网的重要组成构件,从互联网的角度上看,二者平等(不是包含关系)
- 连接到一个广域网或一个局域网上的主机在该网内进行通信时,只需要使用其网络的物理地址
不同点如下所示:
广域网 | 局域网 | |
---|---|---|
覆盖范围 | 很广,通常跨区域 | 较小,通常在一个区域内 |
连接方式 | 结点之间都是点到点连接,但为了提高网络的可靠性, | |
一个结点交换机往往与多个结点交换机相连 | 普遍采用多点接入技术 | |
OSI参考模型层次 | 三层:物理层,数据链路层,网络层 | 两层:物理层,数据链路层 |
着重点 | 强调资源共享 | 强调数据传输 |
广域网中的一个重要问题是路由选择和分组转发。路由选择协议负责搜索分组从某个结点到目的结点的最佳传输路由,以便构造路由表,然后从路由表再构造出转发分组的转发表。分组是通过转发表进行转发的。
3.7.2 PPP协议
点对点协议(Point–to-Point Protocol,PPP)是使用串行线路通信的面向字节的协议,该协议应用在直接连接两个结点的链路上。不可靠。
组成部分
- 链路控制协议(LCP)。一种扩展链路控制协议,用于建立、配置、测试和管理数据链路。
- 网络控制协议(NCP)。PPP协议允许同时采用多种网络层协议,每个不同的网络层协议要用一个相应的NCP来配置,为网络层协议建立和配置逻辑连接。
- 一个将IP数据报封装到串行链路的方法。P数据报在PPP帧中就是其信息部分,这个信息部分的长度受最大传送单元(MTU)的限制。
PPP帧格式如图所示,PPP帧前3个字段和最后两个字段与HDLC帧相同。PPP是面向字节的,因 而所有PPP帧的长度都是整数个字节。
标注字段(F)为7E(01111110),前后各占1字节。
若标注字段出现在信息字段中,就必须做字节填充,使用的控制转义字节是7D (01111101)。
地址字段(A)占1字节,规定为0xFF,
控制字段(C)占1字节,规定为0x03,两者的内容始终是固定不变的。
协议字段占2字节,说明信息段中运载的是什么种类的分组。HDLC无此字段。
信息部分长度可变,大于或等于0且小于或等于1500B。
帧检验序列(FCS),占2字节,即循环冗余码检验中的冗余码。
因为PPP是,点对点的,并不是总线形,所以无须采用CSMA/CD协议,自然就没有最短帧,所以信息段占01500字节,而不是46~1500字节。
PPP链路建立、使用、撤销
- 静止:当线路处于静止状态时,不存在物理层连接。
- 建立:当线路检测到载波信号时,建立物理连接,线路变为建立状态。
- LCP开始选项商定,商定成功后就进入身份验证状态。身份验证通过后,进入网络层协议状态。
- 采用NCP配置网络层,配置成功后,进入打开状态,然后就可进行数据传输。
- 撤销:当数据传输完成后,线路转为终止状态。载波停止后则回到静止状态。
特点
1)PPP提供差错检测但不提供纠错功能,只保证无差错接收(通过硬件进行CRC校验)。它是不可靠的传输协议,因此也不使用序号和确认机制。
2)它仅支持点对点的链路通信,不支持多点线路。
3)PPP只支持全双工链路。
4)PPP的两端可以运行不同的网络层协议,但仍然可使用同一个PPP进行通信。
5)PPP是面向字节的,当信息字段出现和标志字段一致的比特组合时,PPP有两种不同的处理方法:若PPP用在异步线路(默认),则采用字符填充法;若PPP用在SONET/SDH等同步线路,则协议规定采用硬件来完成比特填充(和HDLC的做法一样)。
3.7.3 HDLC协议
高级数据链路控制(HDLC)协议是面向比特的数据链路层协议。实现可靠传输。
- 特点
- 该协议不依赖于任何一种字符编码集
- 数据报文可透明传输,用于实现透明传输的“0比特插入法”易于硬件实现
- 全双工通信,有较高的数据链路传输效率
- 所有帧采用CRC检验,对信息帧进行顺序编号,可防止漏收或重发,传输可靠性高
- 传输控制功能与处理功能分离,具有较大的灵活性。
帧格式
- 标志字段F,为01111110。在接收端只要找到标志字段就可确定一个帧的位置。
- HDLC协议采用比特填充的首尾标志法实现透明传输。
- 地址字段A,共8位,根据不同的传送方式,表示从站或应答站的地址。
- 控制字段C,共8位,HDLC的许多重要功能都靠控制字段来实现。
PPP与HDLC的不同
- PPP协议是面向字节的,HDLC协议是面向比特的。
- PPP帧比HDLC帧多一个2字节的协议字段。当协议字段值为0x0021时,表示信息字段是IP数据报。
- PPP协议不使用序号和确认机制,只保证无差错接收(CRC检验),而端到端差错检测由高层协议负责。HDLC协议的信息帧使用了编号和确认机制,能够提供可靠传输。
3.8 数据链路层设备
3.8.1 网桥
两个或多个以太网通过网桥连接后,就成为一个更大的以太网,而原来的每个以太网就称为一个网段。网桥工作在链路层的MAC子层,可以使以太网各网段成为隔离开的碰撞域。
网桥根据MAC帧的目的地址对帧进行转发和过滤。当网桥收到一个帧时,并不向所有接口转发此帧,而是先检查此帧的目的MAC地址,然后再确定将该帧转发到哪一个接口,或者是把它丢弃(即过滤)。
- 冲突域:在同一个冲突域中的每一个节点都能收到所有被发送的帧。简单的说就是同一时间只能有一台设备发送信息的范围。
- 广播域:网络中能接收任一设备发出的广播帧的所有设备的集合。简单的说如果站点发出一个广播信号,所有能接收到这个信号的设备范围称为一个广播域。
层次 | 设备 | 隔离冲突域 | 隔离广播域 |
---|---|---|---|
网络层 | 路由器 | 能 | 能 |
数据链路层 | 网桥、交换机 | 能 | 不能 |
物理层 | 中继器、集线器 | 不能 | 不能 |
3.8.2 局域网交换机
交换机的原理和特点
局域网交换机,又称以太网交换机,以太网交换机实质上就是一个多端口的网桥,工作在数据链路层。
以太网交换机的每个端口都直接与单台主机或另一个交换机相连,通常都工作在全双工方式。
原理:它检测从以太端口来的数据帧的源和目的地的MAC地址,然后与系统内部的动态查找表进行比较,若数据帧的MAC地址不在查找表中,则将该地址加入查找表中,并将数据帧发送给相应的目的端口。
交换机能经济地将网络分成小的冲突域,为每个工作站提供更高的带宽。
对于传统10Mb/s的共享式以太网,若共有N个用户,则每个用户占有的平均带宽只有总带宽的1/N。
使用交换机时,每个端口到主机的带宽还是10Mb/s,用户在通信时是独占而不是和其他网络用户共享传输媒体的带宽,因此拥有N个端口的交换机的总容量为N×10Mb/s。
特点:
- 以太网交换机的每个端口都直接与单台主机相连(网桥的端口往往连接到一个网段),并且一般都工作在全双工方式。
- 以太网交换机同时连通多对端口,使每对相互通信的主机都能像独占通信媒体那样,无碰撞地传输数据。
- 以太网交换机是一种即插即用设备,其内部的帧的转发表是通过自学习算法自动地逐渐建立起来的。
- 以太网交换机由于使用专用的交换结构芯片,交换速率较高。
- 以太网交换机独占传输媒体的带宽。
交换模式:
直通式交换机:查完目的MAC地址(6B)就立刻转发。延迟小,可靠性低,无法支持具有不同速率的端口的交换。
存储转发式交换机:将帧放入高速缓存,并检查否正确,正确则转发,错误则丢弃。延迟大,可靠性高,可以支持具有不同速率的端口的交换。
以太网交换机一股都具有多种速率的端口,例如可以具有10Mb/s、100Mb/s和1Gb/s的端口的各种组合,因此大大方便了各种不同情况的用户。
交换机的自学习功能
交换机的过滤和转发借助于交换表(switch table)完成。
过滤:决定一个帧是应该转发到某个端口还是应该将其丢弃称。
转发:决定一个帧应该被移动到哪个接口。
交换表:包含多个表项,每个表项包含①一个MAC地址;②连通该MAC地址的交换机端口。
自学习过程:
- A先向B发送一帧,从端口1进入交换机。
- 交换机收到帧后,查找交换表,找不到MAC地址为B的表项。
- 交换机将该帧的源地址A和端口1(A,1)写入交换表,并向除端口1外的所有端口广播这个帧(该帧就是从端口1进入的,因此不应该将它再从端口1转发出去)。
- C和D丢弃该帧,因为目的地址不对。只有B才收下这个目的地址正确的帧。
- B通过端口3向A发送一帧,交换机查找交换表后,发现有表项 (A,1),将该帧从端口1转发给A。同时,将该帧的源地址B和端口 3 (B,3) 写入交换表,表明以后如有发送给B的帧,应该从端口3转发出去。
- 经过一段时间,只要主机C和D也向其他主机发送帧,交换机就会把C和D及对应的端口号写入交换表。这样,转发给任何主机的帧,都能很快地在交换表中找到相应的转发端口。
交换表中的每个表项都设有一定的有效时间,过期的表项会自动删除。这就保证了交换表中的数据符合当前网络的实际状况。
4 网络层
4.1 网络层功能
互联网在网络层的设计思路是,向上只提供简单灵活的、无连接的、尽最大努力交付的数据报服务。也就是说,所传送的分组可能出错、丢失、重复、失序或超时,这就使得网络中的路由器比较简单,而且价格低廉。
4.1.1 异构网络互联
网络互连是指将两个以上的计算机网络,通过一定的方法,用一些中间设备(又称中继系统)相互连接起来,以构成更大的网络系统。根据所在的层次,中继系统分为以下4种:
- 物理层中继系统:转发器,集线器。
- 数据链路层中继系统:网桥或交换机。
- 网络层中继系统:路由器。
- 网络层以上的中继系统:网关。
使用物理层或数据链路层的中继系统时,只是把一个网络扩大了,而从网络层的角度看,它仍然是同一个网络,一般并不称为网络互连。因此网络互连通常是指用路由器进行网络互连和路由选择。路由器是一台专用计算机,用于在互联网中进行路由选择。
TCP/IP体系在网络互连上采用的做法是在网络层采用标准化协议,但相互连接的网络可以是异构的。
上图表示用许多计算机网络通过一些路由器进行互连。由于参加互连的计算机网络都使用相同的IP协议,因此可以把互连后的网络视为如图(b)所示的一个虚拟IP网络。
IP网络:是通过IP协议使性能各异的网络在网络层上看起来好像是一个统一的网络。
4.1.2 路由转发
路由器主要完成两个功能:一是路由选择(确定哪一条路径);二是分组转发(当一个分组到达时所采取的动作)。
- 路由选择:指按照复杂的分布式算法,根据从各相邻路由器所得到的关于整个网络拓扑的变化情况,动态地改变所选择的路由。
- 分组转发:指路由器根据转发表将用户的IP数据报从合适的端口转发出去。
路由表是根据路由选择算法得出的,而转发表是从路由表得出的。转发表的结构应当使查找过程最优化,路由表则需要对网络拓扑变化的计算最优化。在讨论路由选择的原理时,往往不去区分转发表和路由表,而是笼统地使用路由表一词。
4.1.3 SDN基本概念
网络层的主要任务是转发和路由选择。可以将网络层抽象地划分为数据平面(也称转发层面)和控制平面,转发是数据平面实现的功能,而路由选择是控制平面实现的功能。
数据平面:数据平面对于数据处理过程中各种具体处理转发过程。数据平面执行的主要功能是根据转发表进行转发,这是路由器的本地动作。
控制平面:控制平面用于控制和管理网络协议的运行,比如OSPF协议、RIP协议、BGP协议。用于实现路由选择,控制数据报沿着从源主机到目的主机的端到端路径中路由器之间的路由方式。时间长,通常软件解决。
软件定义网络(SDN)是近年流行的一种创新网络架构,它采用集中式的控制平面和分布式的数据平面,两个平面相互分离,控制平面利用控制-数据接口对数据平面上的路由器进行集中式控制,方便软件来控制网络。
在网络的控制平面有一个逻辑上的远程控制器(可以由多个服务器组成)。远程控制器掌握各主机和整个网络的状态,为每个分组计算出最佳路由,通过Openflow协议(也可以通过其他途径)将转发表(在SDN中称为流表)下发给路由器。
路由器的工作很单纯,即收到分组、查找转发表、转发分组。
SDN的可编程性通过为开发者们提供强大的编程接口,使得网络具有很好的编程性。
- 北向接口:对上层应用的开发者,SDN提供的编程接口称为北向接口。北向接口提供了一系列丰富的API,开发者可以在此基础上设计自己的应用,而不必关心底层的硬件细节。
- 南向接口:SDN控制器和转发设备建立双向会话的接口称为南向接口,通过不同的南向接口协议(如Openflow),SDN控制器就可兼容不同的硬件设备,同时可以在设备中实现上层应用的逻辑。
- 东西向接口:SDN控制器集群内部控制器之间的通信接口称为东西向接口,用于增强整个控制平面的可靠性和可拓展性。
SDN优点:
- 全局集中式控制和分布式高速转发,既利于控制平面的全局优化,又利于高性能的网络转发。
- 灵活可编程与性能的平衡,控制和转发功能分离后,使得网络可以由专有的自动化工具以编程方式配置。
- 降低成本,控制和数据平面分离后,尤其是在使用开放的接口协议后,就实现了网络设备的制造与功能软件的开发相分离,从而有效降低了成本。
SDN的问题:
- 安全风险,集中管理容易受攻击,如果崩溃,整个网络会受到影响。
- 瓶颈问题,原本分布式的控制平面集中化后,随着网络规模扩大,控制器可能成为网络性能的瓶颈。
4.1.4 拥塞控制
拥塞:在通信子网中,因出现过量的分组而引起网络性能下降的现象称为拥塞。
例如,某个路由器所在链路的带宽为 R R R B/S,如果IP分组只从它的某个端口进入,那么其速率为rinB/s。当rin=R时,并非好事。
当分组到达路由器的速率接近R时,平均时延急剧增加,并且会有大量的分组被丢弃(路由器端口的缓冲区是有限的),整个网络的吞吐量会骤降,源与目的地之间的平均时延也会变得近乎无穷大。
判断网络是否拥塞方法:观察网络的吞吐量与网络负载的关系
- 轻度拥塞状态:随着网络负载的增加,网络的吞吐量明显小于正常的吞吐量。
- 拥塞状态:网络的吞吐量随着网络负载的增大而下降。
- 死锁状态:网络的负载继续增大,而网络的吞吐量下降到零。
拥塞控制的作用是确保子网能够承载所达到的流量,这是一个全局性的过程,涉及各方面的 行为:主机、路由器及路由器内部的转发处理过程等。单一地增加资源并不能解决拥塞。
流量控制和拥塞控制的区别:
流量控制往往是指在发送端和接收端之间的点对点通信量的控制。流量控制所要做的是抑制发送端发送数据的速率,以便使接收端来得及接收。
而拥塞控制必须确保通信子网能够传送待传送的数据,是一个全局性的问题,涉及网络中所有的主机、路由器及导致网络传输能力下降的所有因素。
拥塞控制的方法:
- 开环控制:在设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。
这是一种静态的预防方法。一旦整个系统启动并运行,中途就不再需要修改。
开环控制手段包括确定何时可接收新流量、何时可丢弃分组及丢弃哪些分组,确定何种调度策略等。所有这些手段的共性是,在做决定时不考虑当前网络的状态。 - 闭环控制:事先不考虑有关发生拥塞的各种因素,采用监测网络系统去监视,及时检测哪里发生了拥塞,然后将拥塞信息传到合适的地方,以便调整网络系统的运行,并解决出现的问题。
闭环控制是基于反馈环路的概念,是一种动态的方法。
4.2 路由算法和路由协议
4.2.1 静态路由与动态路由
路由器转发分组是通过路由表转发的,而路由表是通过各种算法得到的。从能否随网络的通信量或拓扑自适应地进行调整变化来划分,路由算法可以分为如下两大类。
- 静态路由算法(又称非自适应路由算法)。指由网络管理员手工配置的路由信息。
当网络的拓扑结构或链路的状态发生变化时,网络管理员需要手工去修改路由表中相关的静态路由信息。它不能及时适应网络状态的变化,对于简单的小型网络,可以采用静态路由。 - 动态路由算法(又称自适应路由算法)。指路由器上的路由表项是通过相互连接的路由器之间彼此交换信息,然后按照一定的算法优化出来的,而这些路由信息会在一定时间间隙里不断更新,以适应不断变化的网络,随时获得最优的寻路效果。
4.2.2 距离-向量路由算法
距离向量算法
常见的距离-向量路由算法是RIP算法,每个路由器定期与所有相邻路由器交换整个路由表,更新路由项。
这种路由表包含:①每条路径的目的地(另一结点)。②路径的代价(也称距离)。
这里的距离是一个抽象的概念,如RIP就将距离定义为“跳数”。跳数指从源端口到达目的端口所经过的路由器个数,每经过一个路由器,跳数加1。
更新路由表的情况:
被通告一条新的路由,该路由在本结点的路由表中不存在,此时本地系统加入这条新的路由。
路由信息有一条较短的距离,发来的路由信息中有一条到达某个目的地的路由,该路由与当前使用的路由相比,有较短的距离。此时,就用经过发送路由信息的结点的新路由替换路由表中到达那个目的地的现有路由。
距离-向量路由算法的实质是,迭代计算一条路由中的站段数或延迟时间,从而得到到达一个目标的最短(最小代价)通路。
- 问题:大的通信子网导致大的更新报文,路由信息变得很大。
距离-向量路由算法中,路由器只掌握物理相连的邻居及链路费用
RIP(路由信息协议) 封装UDP 应用层协议 只适用于小互联网
RIP是一种分布式的基于距离向量的路由选择协议,其最大优点就是简单。
协议规定:
1)网络中的每一个路由器都要维护从它自己到其他每一个目的网络的距离记录(距离向量)
2)距离也称为跳数,规定从一路由器到直接连接的跳数为1。每经过一个路由器,跳数加1
3)RIP认为好的路由就是它通过的路由器的数目少,即优先选择跳数少的路径
4)RIP允许一条路径最多只能包含15个路由器(即最多允许15跳)距离等于16时,表示网络不可到达
5)RIP默认在任意两个使用RIP的路由器之间每30s广播一次RIP路由更新信息,动态维护路由表
6)在RIP中不支持子网掩码的RIP广播,RIP中每个网络的子网掩码必须相同。在RIP2中,支持变长子网掩码和CIDR
RIP报文格式:
RIP报文由首部和路由部分组成。
RIP的特点:
1)仅和相邻路由器交换信息。
2)路由器交换的信息是当前路由器所知道的全部信息,即自己的路由表。
3)按固定的时间间隔交换路由信息,如每隔30秒。
距离向量算法:每个路由表项目都有三个关键数据: < 目的网络 N ,距离 d ,下一跳路由器地址 X > <目的网络N,距离d,下一跳路由器地址X> <目的网络N,距离d,下一跳路由器地址X>。
1)对地址为X的相邻路由器发来的报文,修改此报文中的所有项目【**’下一跳’的地址都改为X,把所有’距离’的值+1**】
2)对修改后的报文中的每一个项目,进行以下步骤:
- ①当原来的路由表中没有目的网络N,则把该项目添加到路由表中
- ②当原来的路由表中有目的网络N,且下一跳路由器地址【是X】时,用收到的项目替换原路由表中的项目
- ③当原来的路由表中有目的网络N,且下一跳路由器地址【不是X】,若收到的项目中的距离d<路由表中的距离,用收到的项目替换原路由表中的项目,否则什么也不做
3)如果180s(默认超时时间是180s)没有收到相邻路由器的更新路由表,把此相邻路由器记为不可达路由,把距离置为16
4)返回
例:已知路由器R6有表a所示的路由表。现在收到相邻路由器R4发来的路由更新信息,如表b所示。试更新路由器R6的路由表。
先把表b中的距离都加1,并把下一跳路由器都改为R4。得出表c。
把这个表的每一行和表a进行比较。
- 第一行在表a中没有,因此要把这一行添加到表a中。
- 第二行的Net2在表a中有,且下一跳路由器也是R4。因此要更新(距离增大了)。
- 第三行的Net3在表a中有,但下一跳路由器不同。于是就要比较距离。新的路由信息的距离是2,小于原来表中的4,因此要更新。
这样,得出更新后的R6的路由表如表d所示。
在更新完路由后,每一个路由器到每一个目的网络的路由都是最短的
RIP优点:实现简单、开销小、收敛过程较快
收敛:路由器刚开始工作时,只知道直接连接的网络的距离(距离为1),接着每一个路由器也只和数目非常有限的相邻路由器交换并更新路由信息。
经过若干次更新后,所有路由器最终都会知道到达本自治系统任何一个网络的最短距离和下一跳路由器的地址,即“收敛”。
RIP缺点:好消息传得快,坏消息传得慢
1)RIP限制了网络的规模,它能使用的最大距离为15(16表示不可达)。
2)路由器之间交换的是路由器中的完整路由表,因此网络规模越大,开销也越大。
3)网络出现故障时,会出现慢收敛现象(即需要较长时间才能将此信息传送到所有路由器),使更新过程的收敛时间长。
慢收敛例子:
现在假定路由器R1,到网1的链路出了故障,R1无法到达网1。于是路由器R1把到网1的距离改为16(表示到网1不可达),因而在R1的路由表中的相应项目变为“1,16,直接”。但是,很可能要经过30秒钟后R1才把更新信息发送给R2。然而R2可能已经先把自己的路由表发送给了R1,其中有“1,2,R1”这一项。
R1收到R2的更新报文后,误认为可经过R2到达网1,于是把收到的路由信息“1,2,R,”修改为:“1,3,R2”,表明“我到网1的距离是3,下一跳经过R2”,并把更新后的信息发送给R2。
同理,R2接着又更新自己的路由表为“1,4,R1”,以为“我到网1距离是4,下一跳经过R1”。
这样的更新一直继续下去,直到R1和R2到网1的距离都增大到16时,R1和R2才知道原来网1是不可达的。RIP协议的这一特点叫做:好消息传播得快,而坏消息传播得慢。网络出故障的传播时间往往需要较长的时间(例如数分钟)。这是RIP的一个主要缺点。
4.2.3 链路状态路由算法
链路状态路由算法
链路状态路由算法要求每个参与该算法的结点都具有完全的网络拓扑信息,它们执行下述两项任务。
第一,主动测试所有邻接结点的状态。两个共享一条链接的结点是相邻结点,它们连接到同一条链路,或者连接到同一广播型物理网络。
第二,定期地将链路状态传播给所有其他结点(或称路由结点)。
典型的链路状态算法是OSPF算法。
特征:
向本自治系统中所有路由器发送信息(洪泛法)。
洪泛法,即路由器通过所有端 口向所有相邻的路由器发送信息。
设路由器R用洪泛法发出链路状态更新分组。图中用一些小的箭头表示更新分组。第一次先发给相邻的三个路由器。这三个路由器将收到的分组再进行转发时,要将其上游路由器除外。可靠的洪泛法是在收到更新分组后要发送确认(收到重复的更新分组只需要发送一次确认)。图中的空心箭头表示确认分组。
发送的信息是与路由器相邻的所有路由器的链路状态。
OSPF算法中,链路状态的“度量”主要用来表示费用、距离、时延、带宽等。
只有链路状态发生变化,才向所有路由器发送信息。
优点:
每个路由结点使用同样的原始状态数据独立的计算路径。
链路状态不加改变的传播,该算法易于查找故障。
仅运载来自单个结点关于直接链路的信息,其大小与网络中的路由结点数目无关,有更好的规模可伸展性。
链路状态路由算法可以用于大型的或路由信息变化聚敛的互联网环境。因为一个路由器的链路状态只涉及相邻路由器的连通状态,而与整个互联网的规模并无直接关系。
链路状态路由算法中,所有路由器掌握完整的网络拓扑和链路费用信息。
OSPF(开放最短路径优先)协议 网络层协议 封装IP
OSPF特点:
- 1)OSPF对不同的链路可根据IP分组的不同服务类型(TOS)而设置成不同的代价。因此,OSPF对于不同类型的业务可计算出不同的路由,十分灵活。
- 2)如果到同一个目的网络有多条相同代价的路径,那么可以将通信量分配给这几条路径。这称为多路径间的负载平衡。
- 3)所有在OSPF路由器之间交换的分组都具有鉴别功能,因而保证了仅在可信赖的路由器之间交换链路状态信息。
- 4)支持可变长度的子网划分和无分类编址CIDR。
- 5)每个链路状态都带上一个32位的序号,序号越大,状态就越新。
OSPF与RIP的区别:
RIP OSPF 工作层次 应用层 基于UDP 网络层 基于IP 转发范围 相邻路由器 整个本自治系统(洪泛法) 发送内容 整个路由表 相邻路由器链路状态 何时发送 定期交换 收敛慢 链路状态改变(洪泛法) 收敛快 OSPF报文格式:
OSPF直接用IP数据报传送,工作在网络层。
OSPF的基本工作原理:
为了使OSPF能够用于规模很大的网络,OSPF将一个自治系统再划分为若干个更小的范围,叫做区域(area)。每一个区域都有一个32位的区域标识符(用点分十进制表示)。
划分区域后,洪泛法交换链路状态信息的范围局限于每一个区域,减少网络的通信量。在一个区域内部的路由器只知道本区域的完整网络拓扑,而不知道其他区域的网络拓扑的情况。每个区域路由器应不超200个。
OSPF采用层次结构的区域划分,使每个区域能够与其他区域通信。
在上层的区域叫做主干区域backbone area)。主千区域的标识符规定为0.0.0.0。主干区域的作用是用来连通其他在下层的区域。
从其他区域来的信息都由区域边界路由器(area border router)进行概括。如路由器R3,R4和R7。
在主干区域内的路由器叫做主干路由器(backbone router),如R3,R4,R5,R6和R7。
在主干区域内需要一个路由器和本自治系统外的其他自治系统交换路由信息。这样的路由器叫做自治系统边界路由器,如R6。
采用层次划分后,使每一个区域内部交换路由信息的通信量大大减小,因而使OSPF协议能够用于规模很大的自治系统中。
OSPF分组类型:
- 1)问候分组,用来发现和维持邻站的可达性。
- 2)数据库描述分组,向邻站给出自己的链路状态数据库中的所有链路状态项目的摘要信息。
- 3)链路状态请求分组,向对方请求发送某些链路状态项目的详细信息。
- 4)链路状态更新分组,用洪泛法对全网更新链路状态。
- 5)链路状态确认分组,对链路更新分组的确认。
通常每隔10秒,每两个相邻路由器要交换一次问候分组,以便知道哪些站可达。路由器刚开始工作时,OSPF让每个路由器使用数据库描述分组和相邻路由器交换本数据库中已有的链 路状态摘要信息。然后,路由器使用链路状态请求分组,向对方请求发送自己所缺少的某些链路 状态项目的详细信息。经过一系列的这种分组交换,就建立了全网同步的链路数据库。
OSPF链路状态路由算法:
1.每个路由器发现它的邻居结点【HELLO问候分组】,并了解邻居节点的网络地址。
2.设置到它的每个邻居的成本度量metric。
3.构造【DD数据库描述分组】,向邻站给出自己的链路状态数据库中的所有链路状态项目的摘要信息。
4.如果DD分组中的摘要自己都有,则邻站不做处理;如果有没有的或者是更新的,则发送【LSR链路状态请求分组】请求自己没有的和比自己更新的信息。
5.收到邻站的LSR分组后,发送【LSU链路状态更新分组】进行更新。
6.更新完毕后,邻站返回一个【LSAck链路状态确认分组】进行确认。
只要一个路由器的链路状态发生变化:
5.泛洪发送【LSU链路状态更新分组】进行更新。
6.更新完毕后,其他站返回一个【LSAck链路状态确认分组】进行确认。
7.使用Dijkstra根据自己的链路状态数据库构造到其他节点间的最短路径。
OSPF算法例子:
因特网中的一个自治系统的内部结构如下图所示。路由选择协议采用OSPF协议时,计算R6的关于网络N1、N2、N3、N4的路由表。
根据Dijkstra算法,得出以下路径表格,其中主意,经过N3网络路径代价未增加。
R1 R2 R3 R4 R5 N1 N2 N3 N4 第1轮 6 6 第2轮 6 14 6 7 8 第3轮 7 7 6 14 6 7 8 第4轮 7 7 6 14 6 10 10 7 8 路由表如下:
4.2.4 层次路由
层次路由
网络规模扩大,路由器的路由表成比例地增大。这样会消耗大量资源,因此路由选择应按照层次的方式进行。
因特网将整个互联网划分为许多较小的自治系统(AS)(注意一个自治系统中包含很多局域网)。
自治系统(Autonomous System,AS):单一技术管理下的一组路由器,这些路由器使用一种AS内部的路由选择协议和共同的度量来确定分组在该AS内的路由,同时还使用一种AS之间的路由选择协议来确定分组在AS之间的路由。
每个自治系统有权自主地决定本系统内应采用何种路由选择协议。如果两个自治系统需要通信,那么就需要一种在两个自治系统之间的协议来屏蔽这些差异。因此将选择协议分为以下两种类型:
- 内部网关协议(IGP):也称域内路由选择,指一个自治系统内部所使用的路由选择协议,具体的协议有RIP和OSPF等。
- 外部网关协议(EGP):也称域间路由选择,指自治系统之间所使用的路由选择协议,在不同自治系统的路由器之间交换路由信息,并负责为分组在不同自治系统之间选择最优的路径。具体的协议有BGP。
使用层次路由时,OSPF将一个自治系统再划分为若干区域(Area),每个路由器都知道在本区域内如何把分组路由到目的地的细节,但不用知道其他区域的内部结构。因而使OSPF协议能够用于规模很大的自治系统中。
BGP(外部网关协议) 应用层 TCP封装
边界网关协议(Border Gateway Protocol,BGP)是不同自治系统的路由器之间交换路由信息的协议,是一种外部网关协议。
目的:力求寻找一条能够到达目的网络且比较好的路由(不能兜圈子)
困难
- 互联网的规模太大,使得自治系统AS之间路由选择非常困难
- 自治系统AS之间的路由选择必须考虑有关策略。
交换过程
BGP所交换的网络可达性的信息就是要到达某个网络所要经过的一系列AS。
当BGP发言人互相交换了网络可达性的信息后,各BGP发言人就根据所采用的策略从收到的路由信息中找出到达各AS的较好路由。
BGP的工作原理:
每一个自治系统的管理员要选择至少一个路由器(可多个)作为该自治系统的”BGP发言人”
一个BGP发言人与其他自治系统中的BGP发言人要交换路由信息,就要先建立TCP连接
然后在此连接上交换BGP报文以建立BGP会话,再利用BGP会话交换路由信息
当所有BGP发言人都相互交换网络可达性的信息后,各BGP发言人就可找出到达各个自治系统的比较好的路由
BGP发言人交换路径向量
自治系统AS2的BGP发言人通知主干网的BGP发言人:“要到达网络N1,N2,N3和N4可经过AS2。”主干网在收到这个通知后,就发出通知:“要到达网络N1,N2,N3和N4可沿路径(AS1,AS2)。”同理,主干网还可发出通知:“要到达网络N5,N6和N可沿路径(AS1,AS3)。”
BGP报文格式:
特点:
1)BGP协议交换路由信息的结点数量级是自治系统的数量级,比这些自治系统中的网络数少很多
2)每一个自治系统中BGP发言人(或边界路由器)的数目是很少的,这样自治系统之间的路由选择不会很复杂
3)BGP支持CIDR,BGP的路由表包括目的网络前缀、下一跳路由器,以及到达该目的网络所要经过的各个自治系统序列
4)在BGP刚运行时,BGP的邻站交换整个BGP路由表。但以后只需要在发生变化时更新有变化的部分
BGP-4的四种报文
- 打开(Open)报文。用来与相邻的另一个BGP发言人建立关系。
- 更新(Update)报文。用来发送某一路由的信息,以及列出要撤销的多条路由。
- 保活(Keepalive)报文。用来确认打开报文并周期性地证实邻站关系。
- 通知(Notification)报文。用来发送检测到的差错。
RIP、OSPF与BGP的比较如表所示。
协议 | RIP | OSPF | BGP |
---|---|---|---|
类型 | 内部 | 内部 | 外部 |
路由算法 | 距离-向量 | 链路状态 | 路径-向量 |
传递协议 | 应用层 UDP | 网络层 IP | 应用层 TCP |
路径选择 | 跳数最少 | 代价最低 | 较好,非最佳 |
交换结点 | 和本结点相邻的路由器 | 网络中的所有路由器 | 和本结点相邻的路由器 |
交换内容 | 自己的整个路由表 | 与本路由器相邻的所有路由器的链路状态 | 首次:整个路由表 |
非首次:有变化的部分 |
4.3 IPv4
4.3.1 IPv4分组
- IPv4分组的格式
一个IP分组由首部和数据部分组成。首部长度20B固定,后面有可选字段,长度可变。
版本:指IP协议的版本,目前广泛使用的版本号为4。
首部长度:单位是4B,最小为5,表示20B,最大是15,表示60B。
区分服务:指示期望获得哪种类型的服务。
总长度:首部+数据,单位是1B。
标识:16位,用于IP分片,同一数据报的分片使用同一标识。
标志:3位,只有后两位有意义,中间位DF,DF=1,禁止分片;DF=0,允许分片。最低位MF,MF=1,后面“还有分片”;MF=0,代表最后一片/没分片。
片偏移:指出较长分组分片后,某片在原分组中的相对位置;以8B位单位。除了最后一个分片,每个分片数据部分长度一定是8B的整数倍。
生存时间(TTL):IP分组的保质期。经过一个路由器-1变成0则丢弃。
协议:数据部分的协议,占8位。
协议名 ICMP IGMP TCP EGP IGP UDP IPv6 ESP OSPF 字段值 1 2 6 8 9 17 41 50 89 首部检验和:16位,只检验首部。
源IP地址和目的IP地址:32位。
可选字段:0~40B,用来支持排错测量以及安全等措施
填充:全0,把首部补成4B的整数倍
段 | 总长度 | 片偏移 | 首部长度 |
---|---|---|---|
长度 | 1B | 8B | 4B |
- IP数据报分片
最大传送单元(MTU):一个链路层数据报能承载的最大数据量。以太网的MTU是1500字节。
当IP数据报的总长度大于链路MTU时,就需要将IP数据报中的数据分装在多个较小的IP数据报中,这些较小的数据报称为片。 片在目的地的网络层被重新组装。
IP分片利用首部的标识、标志和片偏移三部分完成。
- 标识:创建IP数据报时,源主机为其加一个标识号,同一个数据报分片后,每片具有相同的标识。
- 标志:共3位,只有后两位有意义,
- 中间位DF(Don’t Fragment),DF=1,禁止分片;DF=0,允许分片。
- 最低位MF(More Fragment),MF=1,后面“还有分片”;MF=0,代表最后一片/没分片。
- 片偏移:指出数据报分片后某片在原分组中的相对位置,以8B位单位。除了最后一个分片,每个分片数据部分长度一定是8B的整数倍。
如上图所示,一个长4000B的IP数据报(首部20B,数据报部分3980B)到达路由器后,需要在以太网转发(MTU = 1500B)。需要将3980B数据分片,前2片,每片有效数据部分1480B,首部20B;后一片数据部分为1020B=(3980-1480-1480)B,首部20B。
每一片的DF都为0,表示都允许分片。前两片MF=1,表示并非最后一片;最后一片MF=0,表示为最后一片。
第一片片偏移为0,第二片片偏移为首位数据地址/8=1480/8=185;第三片片偏移=2960/8=370。
4.3.2 IPv4地址与NAT
IPv4地址
连接到因特网的每台主机都分配一个32比特的全球唯一标识符,即IP地址。IP地址由互联网名字和数字地址分配机构ICANN进行分配。
IP地址由网络号和主机号组成。
I P 地址 : : = { < 网络号 > , < 主机号 > } IP地址::=\{<网络号>,<主机号>\} IP地址::={<网络号>,<主机号>}
网络号标志主机(或路由器)所连接到的网络。一个网络号在整个因特网唯一。主机号标志该主机(或路由器)自身。一台主机号在相同网络号范围是唯一的。
IPv4被分为了5类地址,分别适用于不同规模的网络。
网络类型 网络号 用途 A类 前8位,第1位为0(1-126) 用于大型网络 B类 前16位,前2位为10(128-191) 用于中等规模网络 C类 前24位,前3位为110(192~223) 用于小型网络 D类 开头1110(224-239) 多播地址,用于向多个目标发送数据 E类 开头1111(240-255) 保留地址,目前还没有被使用 某些IP地址有着特殊用途,不能做主机IP地址。
- 主机号全为0表示本网络本身,如202.98.174.0。
- 主机号全为1表示本网络的广播地址,又称直接广播地址,如202.98.174.255。
- 127.×.×.×保留为环回自检(Loopback Test)地址,此地址表示任意主机本身,目的地址为环回地址的P数据报永远不会出现在任何网络上。
- 32位全为0,即0.0.0.0表示本网络上的本主机。
- 32位全为1,即255.255.255.255表示整个TCP/P网络的广播地址,又称受限广播地址。实际使用时,由于路由器对广播域的隔离,255.255.255.255等效为本网络的广播地址。
网络类别 最大可用网络数 第一个可用的网络号 最后一个可用的网络号 网络中最大主机数 A 27-2 1 126 224-2 B 214 128.0 191.255 216-2 C 221 192.0.0 223.255.255 28-2 A类地址可用的网络数为27-2,减2的原因是:第一,网络号字段全为0的IP地址是保留地址,意思是“本网络”;第二,网络号为127的P地址是环回自检地址。
网络号 主机号 作为源地址 作为目的地址 用途 全0 全0 可以 不可以 本网范围内表示主机,路由表中用于表示默认路由 (表示整个Internet网络) 全0 特定值 可以 不可以 表示本网内某个特定主机 全1 全1 不可以 可以 本网广播地址(路由器不转发) 特定值 全0 不可以 不可以 网络地址,表示一个网络 特定值 全1 不可以 可以 直接广播地址,对特定网络上的所有主机进行广播 127 任何数 非全0/1 可以 可以 用于本地软件环回测试,称为环回地址 IP地址特点:
IP地址是一种分等级的地址结构。其好处如下:
①在分配IP地址时只分配网络号,而主机号则由得到该网络的单位自行分配,方便了 IP地址的管理;
②路由器仅根据目的主机所连接的网络号来转发分组,减小了路由表所占的存储空间。
IP地址是标志一台主机(或路由器)和一条链路的接口。
当一台主机同时连接到两个网络时,该主机就必须同时具有两个相应的IP地址,每个IP地址的网络号必须与所在网络的网络号相同,且这两个IP地址的主机号是不同的。
IP网络上的一个路由器必然至少应具有两个IP地址(路由器每个端口必须至少分配一个IP地址)。
用网桥连接的若干LAN仍然是同一个网络(同一个广播域),因此该LAN中所有主机的IP地址的网络号必须相同,但主机号必须不同。
在IP地址中,所有分配到网络号的网络(无论是LAN还是WAN)都是平等的。
在同一个局域网上的主机或路由器的IP地址中的网络号必须是一样的。
由于广泛使用无分类IP地址进行路由选择,这种传统分类的IP地址已成为历史。
网络地址转换(NAT)
网络地址转换(NAT)是指通过将专用网络地址(如Intranet)转换为公用地址(如Internet),从而对外隐藏内部管理的IP地址。其优势如下:
- 它使得整个专用网只需要一个全球IP地址就可以与因特网连通。
- 由于专用网本地IP地址是可重用的,所以NAT大大节省了IP地址的消耗。
- 它隐藏了内部网络结构,从而降低了内部网络受到攻击的风险。
为了网络安全,划出了部分IP地址为私有IP地址。其特点如下:
私有IP只用于LAN,不用于WAN连接。因此私有IP地址不能直接用于Internet,必须通过网关利用NAT把私有IP地址转换为Internet中合法的全球IP地址后才能用于Internet。
私有IP地址被LAN重复使用。有效地解决了P地址不足的问题。
私有IP地址网段如下:
- A类:1个A类网段,即10.0.0.0~10.255.255.255。
- B类:16个B类网段,即172.16.0.0~172.31.255.255。
- C类:256个C类网段,即192.168.0.0~192.168.255.255。
在因特网中的所有路由器,对目的地址是私有地址的数据报一律不进行转发。
这种采用私有 IP地址的互联网络称为专用互联网或本地互联网。私有IP地址也称可重用地址。
使用NAT时需要在专用网连接到因特网的路由器上安装NAT软件,NAT路由器至少有一个有效的外部全球IP地址。使用本地地址的主机和外界通信时,NAT路由器使用NAT转换表进行本地IP地址和全球IP地址的转换。
NAT转换表存放着 { 本地 I P 地址:端口 } \{本地IP地址:端口\} {本地IP地址:端口}到 { 全球 I P 地址:端口 } \{全球IP地址:端口\} {全球IP地址:端口}的映射。该端口号是逻辑上的端口。
例,一个宿舍办理了电信宽带,拥有了一个全球IP:138.76.29.7;宿舍内4台主机有了私有地址:192.168.0.0网段。宿舍网关开启NAT功能,NAT表如上图所示。
当路由器LAN端收到源IP为192.168.0.2,2233时,将其映射为138.76.29.7,5001,从WAN口发至因特网。
当路由器从WAN端收到目的地址为138.76.29.7,5060的数据报时,将其映射成192.168.0.3,1234,然后从LAN端口发送给相应的本地主机。
NAT工作原理:
- ①假设用户主机10.0.0.1(随机端口3345)向Web服务器128.119.40.186(端口80)发送请求。
- ②NAT路由器收到IP分组后,为该IP分组生成一个新端口号5001,将IP分组的源地址更改为138.76.29.7(即NAT路由器的全球IP地址),将源端口号更改为5001。NAT路由器在NAT转换表中增加一个表项。
- ③Web服务器并不知道刚抵达的IP分组已被NAT路由器进行了改装,更不知道用户的专用地址,它响应的IP分组的目的地址是NAT路由器的全球IP地址,目的端口号是5001。
- ④响应分组到达NAT路由器后,通过NAT转换表将IP分组的目的IP地址更改为10.0.0.1,将目的端口号更改为3345。
普通路由器在转发P数据报时,不改变其源P地址和目的P地址。而NAT路由器在转发IP数据报时,一定要更换其IP地址(转换源P地址或目的IP地址)。
普通路由器仅工作在网络层,而NAT路由器转发数据报时需要查看和转换传输层的端口号。
4.3.3 子网划分与子网掩码、CIDR
子网划分
由于两级IP地址有以下缺点,于是在IP增加子网号段:
IP地址空间的利用率有时很低
给每个物理网络分配一个网络号会使路由表变得太大而使网络性能变坏
两级的IP地址不够灵活。
子网划分:增加子网号段,使两级IP变成三级IP地址。基本思路如下:
子网划分纯属一个单位内部的事情。单位对外仍然表现为没有划分子网的网络。
从主机号借位作为子网号;三级IP地址结构如下:
I P 地址 = { < 网络号 > , < 子网号 > , < 主机号 > } IP地址=\{<网络号>,<子网号>,<主机号>\} IP地址={<网络号>,<子网号>,<主机号>}凡是从其他网络发送给本单位某台主机的IP数据报,仍然是根据IP数据报的目的网络号先找到连接到本单位网络上的路由器。然后该路由器在收到IP数据报后,按目的网络号和子网号找到目的子网。最后把IP数据报直接交付给目的主机。
性质:
子网中的主机号为全0或全1的地址都不能被指派
子网中的主机号全0的地址为子网的网络号,主机号全1的地址为子网的广播地址
子网掩码
为了告诉主机或路由器对网络进行了子网划分,使用子网掩码来表达对原网络中主机号的借位。
子网掩码是一个与IP地址相对应的、长32bit的二进制串,它由一串1和跟随的一串0组成。1对应于IP地址中的网络号及子网号,而0对应于主机号。
规定所有网络必需使用子网掩码,不划分采用默认子网掩码:
- A类:255.0.0.0
- B类:255.255.0.0
- C类:255.255.255.0
注意:
1)一个主机在设置IP地址信息的同时,必须设置子网掩码
2)同属于一个子网的所有主机以及路由器的相应端口,必须设置相同的子网掩码
3)路由器的路由表中,所包含的信息其主要内容必须有:目的网络地址、子网掩码、下一跳地址
无分类编址CIDR
无分类域间路由选择CIDR是在变长子网掩码的基础上提出的一种消除传统A、B、C类网络划分,并且可以在软件的支持下实现超网构造的一种IP地址的划分方法。 IP地址结构如下:
I P : : = { < 网络前缀 > , < 主机号 > } IP::=\{<网络前缀>,<主机号>\} IP::={<网络前缀>,<主机号>}
CIDR地址块中的地址数一定是2的整数次幕,实际可指派的地址数通常为2N-2;N表示主机号的位数,主机号全0代表网络号,主机号全1为广播地址。 CIDR记法:IP地址后加上“/”,然后写上网络前缀(可以任意长度)的位数。
例如,对于128.14.32.5/20这个地址,它的掩码是20个连续的1和后续12个连续的0,通过逐位相“与”的方法可以得到该地址的网络前缀(或直接截取前20位):
构成超网:将多个子网聚合成一个较大的子网,叫做构成超网,或路由聚合。
路由聚合使得路由表中的一个项目可以表示多个原来传统分类地址的路由,有利于减少路由器之间的信息的交换,从而提高网络性能。
方法:将网络前缀缩短(所有网络地址取交集)。
例如,网络1的地址块是206.1.0.0/17;网络2的地址块是206.1.128.0/17。
可以看出两个网络前16位相同,第17位分别是0和1,因此可以聚合成更大地址块206.1.0.0/16。
如果不使用路由聚合,那么R1的路由表中需要分别有到网络1和网络2的路由表项。聚合后,到网络1和网络2的两条路由就可以聚合成一条到206.1.0.0/16的路由。
最长前缀匹配:使用CIDR时,查找路由表可能得到几个匹配结果(跟网络掩码按位相与),应选择具有最长网络前缀的路由。前缀越长,地址块越小,路由越具体。
CIDR查找路由表的方法:为了更加有效地查找最长前缀匹配,通常将无分类编址的路由表存放在一种层次式数据结构中,然后自上而下地按层次进行查找。这里最常用的数据结构就是二叉线索。
网络层转发分组的过程
分组转发都是基于目的主机所在网络的,这是因为互联网上的网络数远小于主机数,可以极大地压缩转发表的大小。当分组到达路由器后,路由器根据目的IP地址的网络前缀来查找转发表,确定下一跳应当到哪个路由器。
在转发表中,每条路由必须有下面两条信息:
( 目的地址,下一跳地址 ) (目的地址,下一跳地址) (目的地址,下一跳地址)
这样,IP数据报最终一定可以找到目的主机所在目的网络上的路由器(可能要通过多次间接交付),当到达最后一个路由器时,才试图向目的主机进行直接交付。
采用CIDR编址时,如果一个分组在转发表中可以找到多个匹配的前缀,那么应当选择前缀最长的一个作为匹配的前缀,称为最长前缀匹配。
为了更快地查找转发表,可以按照前缀的长短排序,将前缀最长的排在第1行,按前缀长度的降序排列。这样,从第1行最长的开始查找,只要检索到匹配的,就不必再继续查找。
此外,转发表中还可以增加两种特殊的路由:
主机路由:对特定目的主机的IP地址专门指明一个路由,以方便网络管理员控制和测试网络。若特定主机的IP地址是a.b.c.d,则转发表中对应项的目的网络是a.b.c.d/32。
/32表示的子网掩码没有意义,但这个特殊的前缀可以用在转发表中。默认路由:用特殊前缀0.0.0.0/0表示默认路由,全0掩码和任何目的地址进行按位与运算,结果必然为全0,即必然和转发表中的0.0.0.0/0相匹配。只要目的网络是其他网络(不在转发表中),就一律选择默认路由。
分组转发算法如下:
1)从收到的IP分组的首部提取目的主机的IP地址D(即目的地址)。
2)若查找到特定主机路由(目的地址为D),就按照这条路由的下一跳转发分组;否则从转发表中的下一条(即按前缀长度的顺序)开始检查,执行步骤3)。
3)将这一行的子网掩码与目的地址D进行按位与运算。若运算结果与本行的前缀匹配,则查找结束,按照“下一跳”指出的进行处理(或者直接交付本网络上的目的主机,或通过指定接口发送到下一跳路由器)。否则,若转发表还有下一行,则对下一行进行检查,重新执行步骤3)。否则,执行步骤4)。
4)若转发表中有一个默认路由,则把分组传送给默认路由;否则,报告转发分组出错。
4.3.4 ARP、DHCP与ICMP
IP地址与硬件地址
IP地址是网络层使用的地址,它是分层次等级的。
硬件地址是数据链路层使用的地址(MAC地址),它是平面式的。
在网络层及网络层之上使用IP地址,IP地址放在IP数据报的首部,而MAC地址放在MAC帧的首部。通过数据封装,把IP数据报分组封装为MAC帧后,数据链路层看不见数据报分组中的IP地址。
1)在IP层抽象的互联网上只能看到IP数据报。
2)虽然在IP数据报首部中有源IP地址,但路由器只根据目的IP地址进行转发。
3)在局域网的链路层,只能看见MAC帧。IP数据报被封装在MAC帧中,通过路由器转发IP分组时,IP分组在每个网络中都被路由器解封装和重新封装,其MAC帧首部中的源地址和目的地址会不断改变。这也决定了无法使用MAC地址跨网络通信。
4)尽管互连在一起的网络的硬件地址体系各不相同,但IP层抽象的互联网却屏蔽了下层这些复杂的细节。只要我们在网络层上讨论问题,就能够使用统一的、抽象的IP地址研究主机与主机或路由器之间的通信。
地址解析协议(ARP)
无论网络层使用什么协议,在实际网络的链路上传送数据帧时,最终必须使用硬件地址。
**地址解析协议(ARP)**作用是完成IP地址到MAC地址的映射。
ARP表:局域网上各主机和路由器的IP地址到MAC地址的映射表,称ARP表。使用ARP来动态维护ARP表。
工作原理:
主机A欲向本局域网上的某台主机B发送IP数据报时,先在其ARP高速缓存中查看有无主机B的IP地址。
- 如果有,就可查出其对应的硬件地址,再将此硬件地址写入MAC帧,然后通过局域网将该MAC帧发往此硬件地址。
- 如果没有,那么就通过使用目的MAC地址为FFFF-FF-FF-FF-FF的帧来封装并广播ARP请求分组(广播发送),使同一个局域网里的所有主机都收到此ARP请求。
主机B收到该ARP请求后,向主机A发出ARP响应分组(单播发送),分组中包含主机B的IP与MAC地址的映射关系,主机A收到ARP响应分组后就将此映射写入ARP缓存,然后按查询到的硬件地址发送MAC帧。
ARP由于“看到了”IP地址,所以它工作在网络层,而NAT路由器由于“看到了”端口,所以它工作在传输层。
使用ARP的4种典型情况总结如下:
- 发送方是主机(如H1),要把IP数据报发送到本网络上的另一台主机(如H2)。这时H1在网1用ARP找到目的主机H2的硬件地址。
- 发送方是主机(如H1),要把IP数据报发送到另一个网络上的一台主机(如H3)。这时H1用ARP找到与网1连接的路由器R1的硬件地址,剩下的工作由R1来完成。
- 发送方是路由器(如R1),要把IP数据报转发到与R1连接的网络(网2)上的一台主机(如H3)。这时R1在网2用ARP找到目的主机H3的硬件地址。
- 发送方是路由器(如R1),要把IP数据报转发到网3上的一台主机(如H4)。这时R1在网2用ARP找到与网2连接的路由器R2的硬件地址,剩下的工作由R2来完成。
从IP地址到硬件地址的解析是自动进行的,主机的用户并不知道这种地址解析过程
动态主机配置协议(DHCP)
动态主机配置协议(Dynamic Host Configuration Protocol, DHCP)常用于给主机动态分配IP地址。
工作原理:应用层协议,使用客户/服务器方式,客户端和服务端通过广播方式进行交互,基于UDP。
1)需要IP地址的主机在启动时向DHCP服务器广播发送发现报文,这时该主机成为DHCP客户
2)本地网络上所有主机都能收到此广播报文,但只有DHCP服务器才回答此广播报文。DHCP服务器先在其数据库中查找该计算机的配置信息
3)若找到,则返回找到的信息。若找不到,则从服务器的IP地址池中取一个地址分配给该计算机。DHCP服务器的回答报文叫做提供报文
DHCP服务器与客户端交换过程:
- 1)DHCP客户机广播“DHCP发现”消息,试图找到网络中的DHCP服务器,以便从DHCP服务器获得一个IP地址。源地址为0.0.0.0,目的地址为255.255.255.255。
- 2)DHCP服务器收到“DHCP发现”消息后,广播“DHCP提供”消息,其中包括提供给DHCP客户机的IP地址。源地址为DHCP服务器地址,目的地址为255.255.255.255。
- 3)DHCP客户机收到“DHCP提供”消息,如果接受该IP地址,那么就广播“DHCP请求”消息向DHCP服务器请求提供IP地址。源地址为0.0.0.0,目的地址为255.255.255.255。
- 4)DHCP服务器广播“DHCP确认”消息,将IP地址分配给DHCP客户机。源地址为DHCP服务器地址,目的地址为255.255.255.255。
#mermaid-svg-JQ7ZviGKPnUQkqRC {font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC .error-icon{fill:#552222;}#mermaid-svg-JQ7ZviGKPnUQkqRC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JQ7ZviGKPnUQkqRC .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-JQ7ZviGKPnUQkqRC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JQ7ZviGKPnUQkqRC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JQ7ZviGKPnUQkqRC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JQ7ZviGKPnUQkqRC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JQ7ZviGKPnUQkqRC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JQ7ZviGKPnUQkqRC .marker.cross{stroke:#333333;}#mermaid-svg-JQ7ZviGKPnUQkqRC svg{font-family:”trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JQ7ZviGKPnUQkqRC .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-JQ7ZviGKPnUQkqRC text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-JQ7ZviGKPnUQkqRC .actor-line{stroke:grey;}#mermaid-svg-JQ7ZviGKPnUQkqRC .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC .sequenceNumber{fill:white;}#mermaid-svg-JQ7ZviGKPnUQkqRC #sequencenumber{fill:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC .messageText{fill:#333;stroke:#333;}#mermaid-svg-JQ7ZviGKPnUQkqRC .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-JQ7ZviGKPnUQkqRC .labelText,#mermaid-svg-JQ7ZviGKPnUQkqRC .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-JQ7ZviGKPnUQkqRC .loopText,#mermaid-svg-JQ7ZviGKPnUQkqRC .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-JQ7ZviGKPnUQkqRC .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-JQ7ZviGKPnUQkqRC .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-JQ7ZviGKPnUQkqRC .noteText,#mermaid-svg-JQ7ZviGKPnUQkqRC .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-JQ7ZviGKPnUQkqRC .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-JQ7ZviGKPnUQkqRC .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-JQ7ZviGKPnUQkqRC .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-JQ7ZviGKPnUQkqRC .actorPopupMenu{position:absolute;}#mermaid-svg-JQ7ZviGKPnUQkqRC .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-JQ7ZviGKPnUQkqRC .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-JQ7ZviGKPnUQkqRC .actor-man circle,#mermaid-svg-JQ7ZviGKPnUQkqRC line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-JQ7ZviGKPnUQkqRC :root{–mermaid-font-family:”trebuchet ms”,verdana,arial,sans-serif;} 客户端 服务器 DHCP发现 DHCP提供 DHCP请求 DHCP确认 客户端 服务器
DHCP特点:
- DHCP允许网络上配置多台DHCP服务器,当DHCP客户机发出“DHCP发现”消息时,有可能收到多个应答消息。这时,DHCP客户机只会挑选其中的一个,通常挑选最先到达的。
- DHCP服务器分配给DHCP客户的IP地址是临时的,因此DHCP客户只能在一段有限的时间内使用这个分配到的IP地址。DHCP称这段时间为租用期。租用期的数值应由DHCP服务器自己决定,DHCP客户也可在自己发送的报文中提出对租用期的要求。
- DHCP的客户端和服务器端需要通过广播方式来进行交互,原因是在DHCP执行初期,客户端不知道服务器端的IP地址,而在执行中间,客户端并未被分配IP地址,从而导致两者之间的通信必须采用广播的方式。采用UDP而不采用TCP的原因也很明显:TCP需要建立连接,如果连对方的IP地址都不知道,那么更不可能通过双方的套接字建立连接。
- DHCP是应用层协议,因为它是通过客户/服务器模式工作的,DHCP客户端向DHCP服务器请求服务,而其他层次的协议是没有这两种工作方式的。
网际控制报文协议(ICMP)
网际控制报文协议(Internet Control Message Protocol,ICMP)提高IP数据报交付成功的机会。
ICMP是网络层协议。ICMP报文作为IP层数据报的数据,加上数据报的首部,组成IP数据报发送出去。
ICMP分为两类,即ICMP差错报告报文和ICMP询问报文。
ICMP差错报告报文:用于目标主机或到目标主机路径上的路由器向源主机报告差错和异常情况。
ICMP差错报告报文可分为以下5类:
- 终点不可达。当路由器或主机不能交付数据报时,就向源点发送终点不可达报文。
- 源点抑制。当路由器或主机由于拥塞而丢弃数据报时,就向源点发送源点抑制报文。
- 时间超过。当路由器收到生存时间(TTL)为零的数据报时,除丢弃该数据报外,还要向源点发送时间超过报文。当终点在预先规定的时间内不能收到一个数据报的全部数据报片时,就把已收到的数据报片都丢弃,并向源点发送时间超过报文。
- 参数问题。当路由器或目的主机收到的数据报的首部中有的字段的值不正确时,就丢弃该数据报,并向源点发送参数问题报文。
- 改变路由(重定向)。路由器把改变路由报文发送给主机,让主机知道下次应将数据报发送给另外的路由器(可通过更好的路由)。
ICMP差错报告报文格式如下:
把收到的需要进行差错报告的IP数据报的首部和数据字段的前8个字节提取出来,作为ICMP报文的数据字段。再加上相应的ICMP差错报告报文的前8个字节,就构成了ICMP差错报告报文。
提取收到的数据报的数据字段前8个字节是为了得到运输层的端口号(对于TCP和UDP)以及运输层报文的发送序号(对于TCP)。
整个ICMP报文作为IP数据报的数据字段发送给源点。
不应发送ICMP差错报告报文的几种情况如下:
- 1)对ICMP差错报告报文不再发送ICMP差错报告报文。
- 2)对第一个分片的数据报片的所有后续数据报片都不发送ICMP差错报告报文。
- 3)对具有组播地址的数据报都不发送ICMP差错报告报文。
- 4)对具有特殊地址(如127.0.0.0或0.0.0.0)的数据报不发送ICMP差错报告报文。
ICMP询问报文:共有以下几类,常用的是前两类。
- 回送请求和回答报文:主机或路由器向特定目的主机发出的询问,收到此报文的主机必须给源主机或路由器发送ICMP回送回答报文。测试目的站是否可达以及了解其相关状态。
- 时间戮请求和回答报文:请主机或路由器回答当前的日期和时间。用来进行时钟同步和测量时间。
- 掩码地址请求和回答报文
- 路由器询问和通告报文
PING:测试两个主机之间的连通性,使用了ICMP回送请求和回答报文。工作在应用层。
Traceroute: 跟踪一个分组从源点到终点的路径, 使用了ICMP时间超过差错报告报文; 工作在网络层。
协议 | 工作层次 | 功能 |
---|---|---|
ARP | 网络层 | IP到MAC地址的映射 |
DHCP | 应用层;基于UDP;客户/服务器模式 | 动态分配IP地址 |
ICMP | 网络层;基于IP | 检测网络连通性和故障诊断 |
4.4 IPv6
4.4.1 IPv6的主要特点
解决IP地址耗尽问题措施有以下三种:
- ①采用无类别编址CIDR,使IP地址的分配更加合理;
- ②采用网络地址转换(NAT)方法以节省全球IP地址;
- ③采用具有更大地址空间的新版本的IPv6。
其中前两种方法只是延长了IPv4地址分配完毕的时间,只有第三种方法从根本上解决了IP地址的耗尽问题。
IPv6特点如下:
- 1)更大的地址空间。IPv6将地址从IPv4的32位增大到了128位。IPv6的字节数(16B)是IPv4字节数(4B)的平方。
- 2)扩展的地址层次结构。
- 3)灵活的首部格式。
- 4)改进的选项。
- 5)允许协议继续扩充。
- 6)支持即插即用(即自动配置)。
- 7)支持资源的预分配。
- 8)IPν6只有在包的源结点才能分片,是端到端的,传输路径中的路由器不能分片,所以从一般意义上说,IPv6不允许分片(不允许类似IPv4的路由分片)。
- 9)IPv6首部长度必须是8B的整数倍,而IPv4首部是4B的整数倍。
- 10)增大了安全性。身份验证和保密功能是PV6的关键特征。
IPv6数据报格式
IPv6数据报由两大部分组成,即基本首部(base header)和后面的有效载荷(payload)。
有效载荷允许有零个或多个扩展首部(extension header),再后面是数据部分。但所有的扩展首部并不属于IPv6数据报的首部。
与IPv4的首部区别有:
- 取消了首部长度字段,因为它的首部长度是固定的(40字节)。
- 取消了服务类型字段,因为优先级和流标号字段实现了服务类型字段的功能。
- 取消了总长度字段,改用有效载荷长度字段。
- 取消了标识、标志和片偏移字段,因为这些功能已包含在分片扩展首部中。
- 把TTL字段改称为跳数限制字段,但作用是一样的(名称与作用更加一致)。
- 取消了协议字段,改用下一个首部字段。
- 取消了检验和字段,这样就加快了路由器处理数据报的速度。我们知道,在数据链路层对检测出有差错的帧就丢弃。在运输层,当使用UDP时,若检测出有差错的用户数据报就丢弃。当使用TCP时,对检测出有差错的报文段就重传,直到正确传送到目的进程为止。因此在网络层的差错检测可以精简掉。
- 取消了选项字段,而用扩展首部来实现选项功能。
把首部字段不必要功能取消后,使得IPv6首部字段减少到8个,首部结构如下。
版本:指明了协议版本,字段是6。
通信量类:区分数据报的类别和优先级。
流标号:“流”是互联网络上从特定源点到特定终点的一系列数据报。所有属于同个流的数据报都具有同样的流标号。
有效载荷长度:指明数据报扩展首部加数据长度,最大值是64K。
下一个首部:有扩展首部时,标识下一个扩展首部;没有扩展首部时,指出数据应交付的上层协议。
跳数限制:相当于IPv4的TTL,最大为255。
扩展首部功能:IPv6把原来IPv4首部中选项的功能都放在扩展首部中,并把扩展首部留给路径两端的源点和终点的主机来处理,而数据报途中经过的路由器都不处理这些扩展首部(只有一个首部例外,即逐跳选项扩展首部),这样就大大提高了路由器的处理效率。
每个扩展首部都由若干个字段组成,它们的长度也各不同。但所有扩展首部的第一个字段都是8位的“下一个首部”字段。此字段的值指出了在该扩展首部后面的字段是什么。当使用多个扩展首部时,应按以上的先后顺序出现。高层首部总是放在最后面。
4.4.2 IPv6地址
IPv6数据报的目的地址可以是以下三种基本类型地址之一:
- 单播。单播就是传统的点对点通信。
- 多播。多播是一点对多点的通信,分组被交付到一组计算机的每台计算机。
- 任播。这是Pν6增加的一种类型。任播的目的站是一组计算机,但数据报在交付时只交付其中的一台计算机,通常是距离最近的一台计算机。
IPv6地址表示
在IPV6标准中指定了一种比较紧凑的表示法,即把地址中的每4位用一个十六进制数表示,并用冒号分隔每16位,如4BF5:AA12:0216:FEBC:BA5F:039A:BE9A:2170。
当16位域的开头有一些0时,可以采用一种缩写表示法,但在域中必须至少有一个数字。例如,可以把地址4BF5:0000:0000:0000:BA5F:039A:000A:2176缩写为4BF5:0:0:0:BA5F:39A:A:2176。
当有相继的0值域时,还可以进一步缩写。这些域可以用双冒号缩写(::)。双冒号表示法在一个地址中仅能出现一次,因为0值域的个数没有编码,需要从指定的总的域的个数来推算。前述地址可被更紧凑地书写成4BF5::BA5F:39A:A:2176。
IPv6分级
IPv6扩展了IPv4地址的分级概念,为了使路由器能够更快地查找路由。它使用以下3个等级:
- 第一级(顶级)指明全球都知道的公共拓扑
- 第二级(场点级)指明单个场点
- 第三级指明单个网络接口
IPv4向IPv6过渡
从IPv4向IPv6过渡只能采用逐步演进的办法,同时还必须使新安装的IPv6系统能够向后兼容。IPv6系统必须能够接收和转发IPv4分组,并且能够为IPv4分组选择路由。
过渡方法有以下两种:
双栈协议:双协议栈技术就是指在一台设备上同时启用IPv4协议栈和IPv6协议栈。这样的话,这台设备既能和IPv4网络通信,又能和IPv6网络通信。
如果这台设备是一个路由器,那么这台路由器的不同接口上,分别配置了IPv4地址和IPv6地址,并很可能分别连接了IPv4网络和IPv6网络。
如果这台设备是一个计算机,那么它将同时拥有IPv4地址和IPv6地址,并具备同时处理这两个协议地址的功能。
隧道技术:
通过使用互联网络的基础设施在网络之间传递数据的方式。使用隧道传递的数据(或负载)可以是不同协议的数据顿或包。隧道协议将其它协议的数据顿或包重新封装然后通过隧道发送。
4.5 IP组播
4.5.1 组播的概念
为了能够支持像视频点播和视频会议这样的多媒体应用,网络必须实施某种有效的组播机制。
组播:是让源计算机一次发送的单个分组可以抵达用一个组地址标识的若干目标主机,并被它们正确接收。
组播基于UDP协议。当主机想利用组播将单个数据发送给一组主机,源主机把数据发给一个组播地址,组播地址可以标识一组地址。网络把这个数据的副本投递给该组中的每台主机。主机可以同时属于多个组。
在IPv4中,每个组播组都有一个D类地址,要给该组发送的计算机使用这个地址作为目标地址。
主机使用**IGMP(因特网组管理协议)**加入组播组。
主机组播时仅发送一份数据,只有数据在传送路径出现分岔时才将分组复制后继续转发。因此,对发送者而言,数据只需发送一次就可发送到所有接收者,大大减轻了网络的负载和发送者的负担。组播需要路由器的支持才能实现,能够运行组播协议的路由器称为组播路由器。
4.5.2 IP组播地址
IP组播使用D类地址格式。D类地址的前四位是1110,因此D类地址范围是224.0.0.0~239.255.255.255。每个D类IP地址标志一个组播组。
特点:
1)组播数据报也是“尽最大努力交付”,不提供可靠交付,应用于UDP。
2)组播地址只能用于目的地址,不能用于源地址
3)对组播数据报不产生ICMP差错报文。若在PING命令后面键入组播地址,将永远不会收到响应
4)并非所有的D类地址都可作为组播地址
IP组播可以分为两种:
- 一种只在本局域网上进行硬件组播
- 另一种则在因特网的范围内进行组播
在因特网上进行组播的最后阶段,还是要把组播数据报在局域网上用硬件组播交付给组播组的所有成员。
硬件组播
组播IP地址也需要相应的组播MAC地址在本地网络中实际传送帧。IANA拥有的以太网组播MAC地址的范围是从01-00-5E-00-00-00到01-00-5E-7F-FF-FF。不难看出,在每个地址中,只有23位可用作组播。这只能和D类IP地址中的23位有一一对应关系。
D类IP地址可供分配的有28位,可见在这28位中,前5位不能用来构成以太网的硬件地址,如图所示。
收到多播数据报的主机,还要在IP层利用软件进行过滤,把不是本主机要接收的数据报丢弃。
4.5.3 IGMP与组播路由算法
IGMP网际组管理协议 网络层协议 基于IP
目的:IGMP协议让组播路由器知道本局域网上是否有主机(的进程)参加或退出了某个组播组。
工作阶段:
1、某主机要加入组播组,向组播地址发送IGMP报文,声明自己要加入组播
本地组播路由器收到报文,转发给因特网其他组播路由器
2、本地组播路由器周期性探询本地局域网上的主机,以便知道这些主机是否还是组播组的成员。
只要有一个主机对某个组响应,那么组播路由器就认为这个组是活跃的;如果经过几次探询后没有一个主机响应,组播路由器就认为本网络上的没有此组播组的主机,因此就不再把这组的成员关系发给其他的组播路由器。
组播路由器知道的成员关系只是所连接的局域网中有无组播组的成员。
组播路由选择协议
目的:组播路由选择协议目的是找出以源主机为根节点的组播转发树。
组播转发树:
组播路由协议目的是找出以源主机为根节点的组播转发树。
构造树可以避免在路由器之间兜圈子。
在组播转发树上的路由器不会收到重复的组播数据报
对不同的多播组对应于不同的多播转发树;同一个多播组,对不同的源点也会有不同的多播转发树。
算法:
- 基于链路状态的路由选择
- 基于距离-向量的路由选择
- 协议无关的组播(PIM)
4.6 移动IP
4.6.1 移动IP的概念
定义
移动IP技术是指移动站以固定的网络IP地址实现跨越不同网段的漫游功能,并保证基于网络IP的网络权限在漫游过程中不发生任何改变。移动IP的目标是把分组自动地投递给移动站。
移动IP定义了三种功能实体:移动节点、本地代理(也称归属代理)和外地代理。
- 移动节点:具有永久IP地址的移动站。
- 归属代理(本地代理):通常就是连接在归属网络(原始连接到的网络)上的路由器。
- 永久地址(归属地址/主地址):移动站点在归属网络中的原始地址。
- 外部代理(外地代理):通常就是连接在被访网络(移动到另一地点所接入的网络)上的路由器。
- 转交地址(辅地址):可以是外部代理的地址或动态配置的一个地址。
4.6.2 移动IP通信过程
移动IP相关概念的应用
在移动IP中,每个移动站都有一个原始地址,即永久地址(或归属地址),移动站原始连接的网络称为归属网络。永久地址和归属网络的关联是不变的。归属代理通常是连接到归属网络上的路由器,然而它实现的代理功能是在应用层完成的。
当移动站移动到另一地点,所接入的外地网络也称被访网络。被访网络中使用的代理称为外地代理,它通常是连接在被访网络上的路由器。
外地代理有两个重要功能:①要为移动站创建一个临时地址,称为转交地址。转交地址的网络号显然和被访网络一致。②及时把移动站的转交地址告诉其归属代理。
用一个通俗的例子来描述移动IP的通信原理。例如,在以前科技不那么发达的年代,本科毕业时都将走向各自的工作岗位。由于事先并不知道自己未来的准确通讯地址,那么怎样继续和同学们保持联系呢?实际上也很简单。彼此留下各自的家庭地址(即永久地址)。毕业后若要和某同学联系,只要写信寄到该同学的永久地址,再请其家长把信件转交即可。
移动IP通信过程
- A刚进入外部网络:
- 1.获得外部代理的转交地址(外部代理广播报文)。
- 2.移动节点通过外部代理发送注册报文给归属代理(包含永久地址&转交地址)。
- 3.归属代理接收请求,并将移动节点的永久地址和转交地址绑定(以后到达该归属代理的数据报且要发往移动节点的数据报将被封装并以隧道方式发给转交地址),并返回一注册响应报文。
- 4.外部代理接收注册响应,并转发给移动节点。
- A移动到了下一个网络:
- 1.在新外部代理登记注册一个转交地址。
- 2.新外部代理给本地代理发送新的转交地址(覆盖旧的)
- 3.通信
- A回到了归属网络:
- 1.A向本地代理注销转交地址。
- 2.按原始TCP/IP方式通信。
- A刚进入外部网络:
4.7 网络层设备
4.7.1 冲突域和广播域
冲突域
冲突域是指连接到同一物理介质上的所有结点的集合,这些结点之间存在介质争用的现象。
在OSI参考模型中,冲突域被视为第1层概念,像集线器、中继器等简单无脑复制转发信号的第1层设备所连接的结点都属于同一个冲突域,也就是说它们不能划分冲突域。而第2层(网桥、交换机)、第3层(路由器)设备都可以划分冲突域。
广播域
广播域是指接收同样广播消息的结点集合。也就是说,在该集合中的任何一个结点发送一个广播帧,其他能收到这个帧的结点都被认为是该广播域的一部分。
在OSI参考模型中,广播域被视为第2层概念,像第1层(集线器等)、第2层(交换机等)设备所连接的结点都属于同一个广播域。而路由器,作为第3层设备,则可以划分广播域,即可以连接不同的广播域。
通常所说的局域网(LAN)特指使用路由器分割的网络,也就是广播域。
4.7.2 路由器的组成和功能
定义
路由器是一种具有多个输入输出端口的专用计算机,其任务是连接不同的网络(连接异构网络)并完成路由转发。在多个逻辑网络(即多个广播域)互连时必须使用路由器。
路由器转发
- 当源主机要向目标主机发送数据报时,路由器先检查源主机与目标主机是否连接在同一个网络上。
- 如果源主机和目标主机在同一个网络上,那么直接交付而无须通过路由器。
- 如果源主机和目标主机不在同一个网络上,那么路由器按照转发表(路由表)指出的路由将数据报转发给下一个路由器,这称为间接交付。
路由器结构
整个的路由器结构可划分为两大部分:路由选择部分和分组转发部分。
路由选择:根据所选定的路由选择协议构造出路由表,同时经常或定期地和相邻路由器交换路由信息而不断地更新和维护路由表
交换结构:根据转发表(路由表得来)对分组进行转发
分组转发:若收到RIP/OSPF分组等,则把分组送往路由选择处理机;若收到数据分组,则查找转发表并输出
输入端口:输入端口中的查找和转发功能在路由器的交换功能中是最重要的。当一个分组正在查找转发表时,后面又紧跟着从这个输入端口收到另一个分组。
输出端口:若路由器处理分组的速率赶不上分组进入队列的速率,则队列的存储空间最终必定减少到零,这就使后面再进入队列的分组由于没有存储空间而只能被丢弃。
路由器中的输入或输出队列产生溢出是造成分组丢失的重要原因。
4.7.3 路由表与路由转发
路由表根据路由选择算法得出的,主要用途是路由选择,总用软件来实现。
标准的路由表有4个项目:目的网络IP地址、子网掩码、下一跳IP地址、接口。
上图为一个简单的网络拓扑,R1的路由表如下图所示。
转发表由路由表得来,可以用软件实现,也可以用特殊的硬件来实现。转发表必须包含完成转发功能所必需的信息,在转发表的每一行必须包含从要到达的目的网络到输出端口和某些MAC地址信息的映射。
为了减少转发表的重复项目,可以使用一个默认路由代替所有具有相同“下一跳” 的项目,并将默认路由设置得比其他项目的优先级低,如下图所示。
- 转发和路由选择的区别:
- “转发”是路由器根据转发表把收到的P数据报从合适的端口转发出去,它仅涉及一个路由器。
- “路由选择”则涉及很多路由器,路由表是许多路由器协同工作的结果。这些路由器按照复杂的路由算法,根据从各相邻路由器得到的网络拓扑的变化情况,动态改变所选择的路由,并由此构造出整个路由表。
注意,在讨论路由选择的原理时,往往不去区分转发表和路由表的区别,但要注意路由表不等于转发表。分组的实际转发是靠直接查找转发表,而不是直接查找路由表。
5 传输层
5.1 传输层提供的服务
5.1.1 传输层的功能
端到端通信
传输层提供进程和进程(端到端)之间的逻辑通信。与网络层的区别是,网络层提供的是主机之间的逻辑通信。应用进程之间的通信又称端到端的逻辑通信。
这里“逻辑通信”的意思是:传输层之间的通信好像是沿水平方向传送数据,但事实上这两个传输层之间并没有一条水平方向的物理连接。
复用和分用
复用是指发送方不同的应用进程都可以使用同一个传输层协议传送数据
分用是指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程
网络层的复用是指发送方不同协议的数据都可以封装成IP数据报发送出去
网络层的分用是指接收方的网络层在剥去首部后把数据支付给相应的协议
差错检测
传输层检验首部与数据部分;网路层只检验首部。
提供两种不同的传输协议
- 面向连接的传输控制协议TCP:可靠,面向连接,时延大,适用于大文件
- 无连接的用户数据报协议UDP:不可靠,无连接,时延小,适用于小文件。
5.1.2 传输层的寻址与端口
端口的作用
端口能够让应用层的各种应用进程将其数据通过端口向下交付给传输层,以及让传输层知道应当将其报文段中的数据向上通过端口交付给应用层相应的进程。
端口是传输层服务访问点(TSAP),它在传输层的作用类似于IP地址在网络层的作用或MAC地址在数据链路层的作用,只不过IP地址和MAC地址标识的是主机,而端口标识的是主机中的应用进程。
数据链路层的SAP是MAC地址,网络层的SAP是IP地址,传输层的SAP是端口。
在协议栈层间的抽象的协议端口是软件端口,它与路由器或交换机上的硬件端口是完全不同的概念。硬件端口是不同硬件设备进行交互的接口,而软件端口是应用层的各种协议进程与传输实体进行层间交互的一种地址。传输层使用的是软件端口。
端口号
应用进程通过端口号进行标识,端口号长度为16bit,能够表示65536(216)个不同的端口号。
端口号只具有本地意义,即端口号只标识本计算机应用层中的各进程,在因特网中不同计算机的相同端口号是没有联系的。根据端口号范围可将端口分为两类:
服务器端使用的端口号:它又分为两类,最重要的一类是熟知端口号,数值为0~1023,IANA(互联网地址指派机构)把这些端口号指派给了TCP/IP最重要的一些应用程序,让所有的用户都知道。
应用程序 FTP TELNET SMTP DNS TFTP HTTP SNMP 熟知端口号 21 23 25 53 69 80 161 另一类称为登记端口号,数值为1024~49151。它是供没有熟知端口号的应用程序使用的,使用这类端口号必须在LANA登记,以防止重复。
客户端使用的端口号:数值为49152~65535。由于这类端口号仅在客户进程运行时才动态地选择,因此又称短暂端口号(也称临时端口)。通信结束后,刚用过的客户端口号就不复存在,从而这个端口号就可供其他客户进程以后使用。
套接字
在网络中通过IP地址来标识和区别不同的主机,通过端口号来标识和区分一台主机中的不同应用进程,端口号拼接到IP地址即构成套接字Socket。套接字,实际上是一个通信端点,即
套接字 S o c k e t = ( I P 地址:端口号) 套接字Socket=(IP地址:端口号) 套接字Socket=(IP地址:端口号)
它唯一地标识网络中的一台主机和其上的一个应用(进程)。在网络通信中,主机A发给主机B的报文段包含目的端口号和源端口号,源端口号是“返回地址”的一部分,即当B需要发回一个报文段给A时,B到A的报文段中的目的端口号便是A到B的报文段中的源端口号(完全的返回地址是A的P地址和源端口号)。
面向连接服务:在通信双方进行通信之前,必须先建立连接,在通信过程中,整个连接的情况一直被实时地监控和管理。通信结束后,应该释放这个连接。
无连接服务:指两个实体之间的通信不需要先建立好连接,需要通信时,直接将信息发送到“网络”中,让该信息的传递在网上尽力而为地往目的地传送。
5.2 UDP协议
5.2.1 UDP数据报
UDP概述
UDP仅在IP的数据报服务之上增加了两个最基本的服务:复用和分用以及差错检测。
UDP具有如下特点:
- UDP是无连接的,减少开销和发送数据之前的时延。
- UDP使用最大努力交付,即不保证可靠交付。
- UDP是面向报文的,适合一次性传输少量数据的网络应用,
- UDP无拥塞控制,适合很多实时应用。
- 分组首部开销小。TCP有20B的首部开销,而UDP仅有8B的开销。
- UDP支持一对一、一对多、多对一和多对多的交互通信。
UDP的首部格式
UDP数据报包含两部分:UDP首部和用户数据。UDP首部和用户数据。UDP首部有8B,由4个字段组成,每个字段的长度都是2B。
- **源端口:**源端口号。在需要对方回信时选用,不需要时可用全0。
- **目的端口:**目的端口号。这在终点交付报文时必须使用到。
- **长度:**单位字节,UDP数据报的长度(包括首部和数据),其最小值是8(仅有首部)。
- **校验和:**检测UDP数据报在传输中是否有错。有错就丢弃。该字段是可选的,当源主机不想计算校验和时,则直接令该字段为全0。
当传输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口上交给应用进程。
如果接收方UDP发现收到的报文中的目的端口号不正确(即不存在对应于端口号的应用进程),那么就丢弃该报文,并由ICMP发送“端口不可达”差错报文给发送方。
5.2.2 UDP校验
在计算校验和时,要在UDP数据报之前增加12B的伪首部,伪首部并不是UDP的真正首部。只是在计算校验和时,临时添加在UDP数据报的前面,得到一个临时的UDP数据报。校验和就是按照这个临时的UDP数据报来计算的。伪首部既不向下传送又不向上递交,而只是为了计算校验和。
UDP校验和的计算方法和IP数据报首部校验和的计算方法相似。但不同的是,IP数据报的校验和只检验IP数据报的首部,但UDP的校验和则检查首部和数据部分。
检验过程:
- 发送方首先把全零放入校验和字段并添加伪首部,然后把UDP数据报视为许多16位的字串接起来。
- 若UDP数据报的数据部分不是偶数个字节,则要在数据部分末尾填入一个全零字节(但此字节不发送)。
- 然后按二进制反码计算出这些16位字的和,将此和的二进制反码写入校验和字段,并发送。
- 接收方把收到的UDP数据报加上伪首部(如果不为偶数个字节,那么还需要补上全零字节)后,按二进制反码求这些16位字的和。
- 当无差错时其结果应为全1,否则就表明有差错出现,接收方就应该丢弃这个UDP数据报。
计算UDP检验和的例子:
二进制反码运算求和:将所有的字相加,如果相加过程中最高位产生了进位,就将进位加到最低位上,这叫做回卷。
5.3 TCP协议
5.3.1 TCP协议的特点
TCP是在不可靠的IP层之上实现的可靠的数据传输协议,它主要解决传输的可靠、有序、无丢失和不重复问题。
主要特点如下:
1)TCP是面向连接(虚连接)的传输层协议
2)每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
3)TCP 提供可靠交付的服务,保证传送的数据无差错、不丢失、不重复且有序
4)TCP提供全双工通信,两端都有发送缓存和接受缓存。
发送缓存用来暂时存放以下数据:①发送应用程序传送给发送方TCP准备发送的数据;②TCP已发送但尚未收到确认的数据。
接收缓存用来暂时存放以下数据:①按序到达但尚未被接收应用程序读取的数据;②不按序到达的数据。
5)TCP是面向字节流的。虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。
5.3.2 TCP报文段
TCP传送的数据单元称为报文段。TCP报文段既可以用来运载数据,又可以用来建立连接、释放连接和应答。
一个TCP报文段分为首部和数据两部分,整个TCP报文段作为IP数据报的数据部分封装在IP数据报中,其首部的前20B是固定的。TCP首部最短为20B,后面有4N字节是根据需要而增加的选项,长度为4B的整数倍。
源端口和目的端口:各占2个字节,分别写入源端口号和目的端口号。
序号:在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,本字段表示本报文段所发送数据的第一个字节的序号。
确认号:期望收到对方下一个报文段的第一个数据字节的序号。若确认号为N,则证明到序号N-1为止的所有数据都已正确收到。
数据偏移(首部长度):TCP报文段的数据起始处距离TCP报文段的起始处有多远,以4B位单位,即1个数值是4B。
保留。占6位,保留为今后使用,但目前应置为0。
控制位:
- 紧急位URG:URG=1时,标明此报文段中有紧急数据,是高优先级的数据,应尽快传送,不用在缓存里排队,配合紧急指针字段使用。
- 确认位ACK:ACK=1时确认号有效,在连接建立后所有传送的报文段都必须把ACK置为1。
- 推送位PSH:PSH=1时,接收方尽快交付接收应用进程,不再等到缓存填满再向上交付。
- 复位RST:RST=1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立传输链接。
- 同步位SYN:SYN=1时,表明是一个连接请求/连接接受报文。
- 终止位FIN:FIN=1时,表明此报文段发送方数据已发完,要求释放连接
窗口:指的是发送本报文段的一方的接收窗口,即现在允许对方发送的数据量。
例如,设确认号是701,窗口字段是1000。这表明,从701号算起,发送此报文段的一方还有接收1000字节数据(字节序号为701~1700)的接收缓存空间。
检验和:检验首部+数据,检验时要加上12B伪首部,第四个字段为6。
紧急指针:URG=1时才有意义,指出本报文段中紧急数据的字节数(紧急数据在报文段数据的最前面)。
选项:长度可变。最大报文段长度MSS、窗口扩大、时间戳、选择确认。
填充:这是为了使整个首部长度是4B的整数倍。
5.3.3 TCP连接管理
TCP是面向连接的协议,因此每个TCP连接都有三个阶段:连接建立、数据传送和连接释放。TCP连接的管理就是使运输连接的建立和释放都能正常进行。
TCP连接的建立
在TCP连接建立的过程中,要解决以下三个问题:
- 1)要使每一方能够确知对方的存在。
- 2)要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项、时间戳选项及服务质量等)。
- 3)能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
TCP连接的建立采用客户/服务器模式。主动发起连接建立的应用进程称为客户(Client),而被动等待连接建立的应用进程称为服务器(Server)。
TCP连接的端口即为套接字(Socket)或插口,每条TCP连接唯一地被通信的两个端点(即两个套接字)确定。
连接建立过程经历3个步骤,称为三次握手。
连接建立前,A、B创建传输控制模块TCB,服务器进程处于LISTEN(收听)状态,等待客户的连接请求。
1)客户机先向服务器发送一个连接请求报文段。它不含应用层数据,其首部中的SYN标志位=1,另外,客户机要随机选择一个起始序号seq=x。TCP客户进程进入SYN-SENT(同步已发送)状态。
2)服务器收到连接请求报文段后,如同意就向客户机发确认,并为该连接分配缓存和变量。
其中,SYN和ACK=1,确认号字段的值ack=x+1,并且服务器随机产生起始序号seq=y,确认报文段同样不包含应用层数据。TCP服务器进程进入SYN-RCVD(同步收到)状态。
3)当客户机收到确认报文段后,还要向服务器给出确认,并且也要给该连接分配缓存和变量。
其中ACK标志位=1,序号字段seq=x+1,确认号字段ack=y+1,该报文段可以携带数据,如果不携带数据则不消耗序号。TCP客户进程进入ESTABLISHED(已建立连接)状态。
要A第三次确认,是为了防止己失效的连接请求报文段突然又传送到了B,因而产生错误。
防止第一次发送的连接请求报文段滞后到达,A在接收到B的确认就开始传送数据,而B确以为建立了新的连接而无法接收,导致数据丢失。
服务器端的资源是在完成第二次握手时分配的,而客户端的资源是在完成第三次握手时分配的,这就使得服务器易于受到SYN洪泛攻击。
SYN洪泛攻击的原理和过程如下:
- 攻击者向服务器发送大量的SYN数据包,请求建立连接,但是故意伪造或随机生成源IP地址,使服务器无法回复。
- 服务器收到SYN数据包后,回复SYN-ACK数据包,并为每个连接分配一个缓冲区,等待客户端的ACK数据包,进入SYN-RCVD状态。
- 由于源IP地址是伪造或随机的,服务器无法收到客户端的ACK数据包,导致缓冲区被占用,无法处理其他的连接请求。
- 当缓冲区满了后,服务器就无法接受新的连接请求,从而拒绝服务。
解决办法:设置SYN cookie,即在回复SYN-ACK数据包时,不分配缓冲区,而是将一些信息编码在序列号中,等到收到ACK数据包时再解码恢复。
TCP连接的释放
参与一条TCP连接的两个进程中的任何一个都能终止该连接,连接结束后,主机中的“资源”(缓存和变量)将被释放。TCP连接释放的过程通常称为四次握手。
1)客户端发送连接释放报文段,停止发送数据,主动关闭TCP连接。FIN=1,seq=u,它等于前面已传送过的数据的最后一个字节的序号加1。TCP客户进程进入FIN-WAIT-1(终止等待1)状态。
2)服务器端回送一个确认报文段,ACK=1,seq=v,ack=u+1,客户到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。服务器进入CLOSE-WAIT(关闭等待)状态。客户收到后进入FIN-WAIT-2(终止等待2)状态。
但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭。
3)服务器端发完数据,就发出连接释放报文段,主动关闭TCP连接。FIN=1,ACK=1,seq=w,ack=u+1。服务器进入LAST-ACK(最后确认)状态。
4)客户端回送一个确认报文段,ACK=1, seq=u+1, ack=w+1,客户进入进入到TIME-WAIT(时间等待)状态。再等到时间等待计时器设置的2MSL(最长报文段寿命)后,连接彻底关闭。客户机和服务器进入CLOSED(连接关闭)状态。
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
- 第一,为了保证A发送的最后一个ACK报文段能够到达B。
- 第二,防止“已失效的连接请求报文段”出现在本连接中。
除时间等待计时器外,TCP还设有一个保活计时器(keepalive timer)。
就是使用保活计时器。服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两小时。若两小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发送10个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭这个连接。
5.3.4 TCP可靠传输
TCP的任务是在IP层不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务。TCP使用了校验、序号、确认和重传等机制来达到这一目的。
可靠,指的是保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。
序号
TCP连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
TCP连接传送的数据流中的每个字节都编上一个序号。序号字段的值是指本报文段所发送的数据的第一个字节的序号。如图所示,假设A和B之间建立了一条TCP连接,A的发送缓存区中共有10B,序号从0开始标号,第一个报文包含第0~2个字节,则该TCP报文段的序号是0,第二个报文段的序号是3。
确认
TCP首部的确认号是期望收到对方的下一个报文段的数据的第一个字节的序号。
TCP默认使用累计确认,即TCP只确认数据流中至第一个丢失字节为止的字节。
重传
有两种事件会导致TCP对报文段进行重传:超时和冗余ACK。
超时重传
TCP每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到期但还没有收到确认,就要重传这一报文段。
TCP采用自适应算法,动态改变重传时间RTTs(加权平均往返时间)
冗余ACK(冗余确认)
TCP规定每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号。
当发送方收到对同一个报文段的3个冗余ACK时,就可以认为跟在这个被确认报丈段之后的报文段已经丢失。
快速重传的例子:
发送方已发送1,2,3,4,5报文段
- 接收方收到1,返回给1的确认(确认号为2的第一个字节)
- 接收方收到3,仍返回给1的确认(确认号为2的第一个字节)
- 接收方收到4,仍返回给1的确认(确认号为2的第一个字节)
- 接收方收到5,仍返回给1的确认(确认号为2的第一个字节)
- 发送方收到3个对于报文段1的冗余ACK,认为2报文段丢失,重传2号报文段。
5.3.5 TCP流量控制
TCP提供流量控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性。TCP提供一种基于滑动窗口协议的流量控制机制。
滑动窗口:
- 接收窗口rwnd:接收端维护,接收端当前的接收缓存大小。
- 拥塞窗口cwnd:发送端维护,发送端根据当前网络的拥塞程度而确定的窗口值。
- 发送窗口:由发送端维护,发送端在接收到下一个确认前能够发送的最大字节数。
- 发送窗口=min(接收窗口,拥塞窗口)
在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,即接收窗口rwnd(接收方设置确认报文段的窗口字段来将rwnd通知给发送方),
发送方的发送窗口取接收窗口rwnd和拥塞窗口cwnd的最小值。TCP的窗口单位是字节,不是报文段。
如上图所示,设A向B发送数据。在连接建立时,B的接收窗口rwnd=400。接收方主机B进行了三次流量控制,这三个报文段都设置了ACK=1,只有在ACK=1时确认号字段才有意义。第一次把窗口减小到rwnd=300,第二次又减到rwnd=100,最后减到rwnd=0,即不允许发送方再发送数据。这使得发送方暂停发送的状态将持续到B重新发出一个新的窗口值为止。
传输层和数据链路层的流量控制的区别是:
- 传输层定义端到端用户之间的流量控制,数据链路层定义两个中间的相邻结点的流量控制。
- 数据链路层的滑动窗口协议的窗口大小不能动态变化,传输层的则可以动态变化。
5.3.6 TCP拥塞控制
拥塞控制是指防止过多的数据注入网络,保证网络中的路由器或链路不致过载,是全局性过程。出现拥塞时,端点并不了解拥塞发生的细节,对通信连接的端点来说,拥塞往往表现为通信时延的增加。
发送窗口的上限值 = m i n [ r w n d , c w n d ] 发送窗口的上限值=min[rwnd,cwnd] 发送窗口的上限值=min[rwnd,cwnd]
因特网建议标准定义了进行拥塞控制的4种算法:慢开始、拥塞避免、快重传和快恢复。
慢开始和拥塞避免
慢开始:
1)先令拥塞窗口cwnd=1(即一个最大报文段长度MSS)。
2)在每收到一个对新的报文段的确认后,将cwnd加1,即增大一个MSS(拥塞窗口加倍)。
为了便于理解,图中的窗口单位不使用字节而使用报文段的个数
拥塞避免:
1)发送端的拥塞窗口cwnd每经过一个往返时延RTT就增加一个MSS的大小,而不是加倍,使cwnd按线性规律缓慢增长(即加法增大)
2)当出现一次超时(网络拥塞)时,则令慢开始门限ssthresh等于当前cwnd的一半(即乘法减小)
根据cwnd的大小执行不同的算法,可归纳如下:
- 当cwnd<ssthresh时,使用慢开始算法。
- 当cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法。
- 当cwnd=ssthresh时,既可使用慢开始算法,又可使用拥塞避免算法(通常做法)。
网络拥塞处理
① 执行慢开始算法,拥塞窗口cwnd置为1,每收到一个ACK,cwnd加1,即每个轮次拥塞窗口翻倍。
② 达到ssthresh初始值16,执行拥塞避免算法,每个轮次拥塞窗口加1。
③ 在cwnd达到24时,出现超时,发送方判断网络拥塞;调整门限ssthresh为12,cwnd置1,重新慢开始。当拥塞窗口到达12时,开始执行拥塞避免。
当网络出现拥塞时,无论在什么阶段,只要发送方检测到超时事件的发生(没有按时收到确认。重传计时器超时),就要把慢开始门限ssthresh设置为出现拥塞时的发送方cwnd值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。
快重传和快恢复
快重传和快恢复算法是对慢开始和拥塞避免算法的改进。
快重传:收到3个重复的确认执行快重传算法。
快恢复:
当发送端收到连续三个冗余ACK时,就执行“乘法减小”算法,把慢开始门限ssthresh设置为出现拥塞时发送方cwnd的一半。与慢开始(将拥塞窗口cwnd设置为1)不同之处是它把cwnd的值设置为慢开始门限ssthresh改变后的数值,然后开始执行拥塞避免算法(加法增大),使拥塞窗口缓慢地线性增大。
在流量控制中,发送方发送数据的量由接收方决定,而在拥塞控制中,则由发送方自己通过检测网络状况来决定。实际上,慢开始、拥塞避免、快重传和快恢复几种算法是同时应用在拥塞控制机制中。
四种算法使用的总结:
在TCP连接建立和网络出现超时时,采用慢开始和拥塞避免算法;
当发送方接收到冗余ACK时,采用快重传和快恢复算法。
6 应用层
6.1 网络应用模型
6.1.1 客户/服务器模型
在客户/服务器(Client/Server,C/S)模型中,有一个总是打开的主机称为服务器,它服务于许多来自其他称为客户机的主机请求。
服务器:提供计算服务的设备
特点:①永久提供服务;②永久性访问地址/域名
客户机:请求计算服务的主机。
特点:
1)与服务器通信,使用服务器提供的服务
2)间歇性接入网络
3)可能使用动态IP地址
4)不与其他客户机直接通信
工作流程:
- 服务器处于接收请求的状态。
- 客户机发出服务请求,并等待接收结果。
- 服务器收到请求后,分析请求,进行必要的处理,得到结果并发送给客户机。
客户/服务器模型的主要特点
1)网络中各计算机的地位不平等,服务器可以通过对用户权限的限制来达到管理客户机的目的,使它们不能随意存储/删除数据,或进行其他受限的网络活动。
整个网络的管理工作由少数服务器担当,因此网络的管理非常集中和方便。
2)客户机相互之间不直接通信。例如,在Wb应用中两个浏览器并不直接通信。
3)可扩展性不佳。受服务器硬件和网络带宽的限制,服务器支持的客户机数有限。
应用:Web、文件传输协议(FTP)、远程登录和电子邮件等。
6.1.2 P2P模型
在P2P模型中,各计算机没有固定的客户和服务器划分。相反,任意一对计算机一一称为对等方(Peer),直接相互通信。每个结点既作为客户访问其他结点的资源,也作为服务器提供资源给其他结点访问。
P2P模型的特点:
- 不存在永远在线的服务器,每个主机既可以提供服务,也可以请求服务
- 任意端系统/节点之间可以直接通讯,多个客户机之间可以直接共享文档
- 节点间歇性接入网络,节点可能改变IP地址
- 多个客户机之间可以直接共享文档
- 可扩展性好
- 网络健壮性强
P2P模型缺点:
在获取服务的同时,还要给其他结点提供服务,因此会占用较多的内存,影响整机速度。
应用:PPlive、Bittorrent和电驴等。
6.2 域名系统(DNS)
域名系统(Domain Name System,DNS)是因特网使用的命名系统,用来把便于人们记忆的具有特定含义的主机名(www.baidu.com)转换为便于机器处理的IP地址。
DNS系统采用客户/服务器模型,其协议运行在UDP之上,使用53号端口。
DNS分为3部分:层次域名空间、域名服务器和解析器。
6.2.1 层次域名空间
因特网采用层次树状结构的命名方法。采用这种命名方法,任何一个连接到因特网的主机或路由器,都有一个唯一的层次结构名称,即域名(Domain Name)。
“域”(domain)是名字空间中一个可被管理的划分。域还可以划分为子域,而子域还可继续划分为子域的子域,这样就形成了顶级域、二级域、三级域,等等。
从语法上讲,每一个域名都由标号(label)序列组成,而各标号之间用点隔开。
标号
1)标号中的英文不区分大小写
2)标号中除连字符”-“外不能使用其他的标点符号
3)每一个标号不超过63个字符,多标号组成的完整域名最长不超过255个字符
4)级别最低的域名写在最左边,而级别最高的顶级域名写在最右边
域名树
根:域名树最上面的是根,但没有对应的名字。它用一个点(.)表示,也称为根域或根区。
顶级域名(Top Level Domain,TLD)分为如下三大类:
国家顶级域名:cn,us,uk
通用顶级域名:com,net,org,gov,int,aero,museum,travel
基础结构域名/反向域名:arpa
二级域名:
类别域名:ac,com,edu,gov,mil,net,org
行政区域名:用于我国各省、自治区、直辖市bj,js
自己注册的域名:cctv,google
凡是在顶级域名com下注册的单位都获得了一个二级域名
三级域名:www、mail
域名树的树叶就是单台计算机的名字,它不能再继续往下划分子域了。
6.2.2 域名服务器
因特网的域名系统被设计成一个联机分布式的数据库系统,并采用客户/服务器模型。
域名到IP地址的解析是由运行在域名服务器上的程序完成的,一个服务器所负责管辖的(或有权限的)范围称为区。每个区设置相应的权限域名服务器,用来保存该区中的所有主机的域名到IP地址的映射。
每个域名服务器不但能够进行一些域名到IP地址的解析,而且还必须具有连向其他域名服务器的信息。当自己不能进行域名到IP地址的转换时,能够知道到什么地方去找其他域名服务器。
DNS使用了大量的域名服务器,它们以层次方式组织。没有一台域名服务器具有因特网上所有主机的映射,相反,该映射分布在所有的DNS上。DNS层次结构如图所示。
根域名服务器
根域名服务器是最高层次的域名服务器,所有的根域名服务器都知道所有的顶级域名服务器的IP地址。
任何本地域名服务器,若无法解析一个域名,就先求助于根域名服务器。通常不直接把待查询的域名直接转换成IP地址,而是告诉本地域名服务器下一步应找哪个顶级域名服务器进行查询
顶级域名服务器
责管理在该顶级域名服务器注册的所有二级域名。
收到DNS查询请求时,就给出相应的回答(可能是最后的结果,也可能是下一步应当查找的域名服务器的IP地址)
授权域名服务器(权限域名服务器)
负责一个区的域名服务器。每台主机都必须在授权域名服务器处登记,授权域名服务器总是能够将其管辖的主机名转换为该主机的地址。
本地域名服务器
当一个主机发出DNS查询请求时,这个查询请求报文就发给本地域名服务器。
每一个因特网服务提供者ISP(一个大学,甚至一个大学里的系)都可以拥有一个本地域名服务器。
6.2.3 域名解析过程
定义
正向解析:是指把域名映射成为IP地址的过程;
反向解析:是指把IP地址映射成为域名的过程。
递归查询
本地域名服务器只需向根域名服务器查询一次,后面的几次查询都是递归地在其他几个域名服务器之间进行的[步骤③~⑥]。在步骤⑦中,本地域名服务器从根域名服务器得到了所需的IP地址,最后在步骤⑧中,本地域名服务器把查询结果告诉发起查询的主机。
由于该方法给根域名服务造成的负载过大,所以在实际中几乎不使用。
递归与迭代相结合的查询
主机向本地域名服务器的查询采用的是递归查询;本地域名服务器向根域名服务器的查询采用迭代查询。
假定某客户机想获知域名为y.abc.com主机的IP地址,域名解析的过程(共使用8个UDP报文):
①客户机向其本地域名服务器发出DNS请求报文
②本地域名服务器收到请求后,查询本地缓存,假设没有该记录,则以DNS客户的身份向根域名服务器发出解析请求,
③根域名服务器收到请求后,判断该域名属于.com域,将对应的顶级域名服务器dns.com的IP地址返回给本地域名服务器
④本地域名服务器向顶级域名服务器dns.com发出解析请求报文
⑤顶级域名服务器dns.com收到请求后,判断该域名属于abc.com域,将对应的授权域名服务器dns.abc.com的IP地址返回给本地域名服务器6本地域名服务器向授权域名服务器dns.abc.com发起解析请求报文。
⑦授权域名服务器 dns.abc.com收到请求后,将查询结果返回给本地域名服务器。
⑧本地域名服务器将查询结果保存到本地缓存,同时返回给客户机。
为了提高DNS的查询效率,并减少因特网上的DNS查询报文数量,在域名服务器中广泛地使用了高速缓存。
查询过的DNS信息可以暂时缓存到高速缓存,再次查询相同域名可直接提供IP地址。
6.3 文件传输协议(FTP)
6.3.1 FTP的工作原理
文件传输协议(File Transfer Protocol,FTP)是因特网上使用得最广泛的文件传输协议。基于TCP,可靠传输。基于==客户/服务器(C/S)==的协议。
用户通过一个客户机程序连接至在远程计算机上运行的服务器程序。依照FTP协议提供服务,进行文件传送的计算机就是FTP服务器。连接FTP服务器,遵循FTP协议与服务器传送文件的电脑就是FTP客户端。
FTP提供交互式的访问,允许客户指明文件的类型与格式,并允许文件具有存取权限。它屏蔽了各计算机系统的细节,因而适合于在异构网络中的任意计算机之间传送文件。
功能
①提供不同种类主机系统(硬、软件体系等都可以不同)之间的文件传输能力。
②以用户权限管理的方式提供用户对远程FTP服务器上的文件管理能力。
③以匿名FTP的方式提供公用文件共享的能力。
FTP的服务器进程由两大部分组成:
- 一个主进程,负责接收新的请求
- 另外有若干从属进程,负责处理单个请求。
工作步骤:
- ①打开熟知端口21(控制端口),使客户进程能够连接上。
- ②等待客户进程发连接请求。
- ③启动从属进程来处理客户进程发来的请求。主进程与从属进程并发执行,从属进程对客户进程的请求处理完毕后即终止。
- ④回到等待状态,继续接收其他客户进程的请求。
6.3.2 控制连接与数据连接
FTP在工作时使用两个并行的TCP连接:一个是控制连接(服务器端口号21),一个是数据连接(服务器端口号20)。使用两个不同的端口号可以使协议更容易实现。控制连接始终保持;数据连接保持一会。
控制连接
服务器监听在21号端口,等待客户连接用来传输控制信息(如连接请求、传送请求)。控制信息都是以7位ASCII 格式传送的。
FTP客户发出的传送请求,通过控制连接发送给服务器端的控制进程,但控制连接并不用来传送文件。
在整个会话期间一直保持打开状态。
数据连接
服务器端的控制进程在接收到FTP客户发送来的文件传输请求后就创建“数据传送进程”和“数据连接”。
用来连接客户端和服务器端的数据传送进程,数据传送进程完成文件的传送,在传送完毕后关闭“数据传送连接”结束运行。
数据连接有两种传输模式:主动模式PORT和被动模式PASV。
主动模式PORT
客户端连接到服务器的21端口,登录成功后要读取数据时,客户端随机开放一个端口,并发送命令告知服务器,服务器收到PORT命令和端口号后,通过20端口和客户端开放的端口连接,发送数据。
被动模式PASV
客户瑞要读取数据时,发送PASV命令到服务器,服务器在本地随机开放一个端口,并告知客户端,客户端再连接到服务器开放的端口进行数据传输。
主动模式传送数据是**“服务器”连接到“客户端”的端口**;被动模式传送数据是**“客户端”连接到“服务器”的端口**。
FTP传输模式
文本模式:ASCII模式,以文本序列传输数据;
二进制模式:Binary模式,以二进制序列传输数据
性质
- 提供交互式的访问
- 允许客户指明文件的类型与格式
- 允许文件具有存取权限
- 屏蔽了各计算机系统的细节,适合在异构网络中任意计算机之间传送文件
6.4 电子邮件
6.4.1 电子邮件系统的组成结构
电子邮件是一种异步通信方式,通信时不需要双方同时在场。电子邮件把邮件发送到收件人使用的邮件服务器,并放在其中的收件人邮箱中,收件人可以随时上网到自己使用的邮件服务器进行读取。
组成构件
- 用户代理(UA):用户与电子邮件系统的接口。用户代理向用户提供一个很友好的接口来发送和接收邮件,用户代理至少应当具有撰写、显示和邮件处理的功能。通常情况下,用户代理就是一个运行在PC上的程序(电子邮件客户端软件),常见的有Outlook和Foxmail等。
- 邮件服务器:它的功能是发送和接收邮件,同时还要向发信人报告邮件传送的情况(已交付被拒绝、丢失等)。邮件服务器采用客户服务器方式工作,但它必须能够同时充当客户和服务器。
- 邮件发送协议和读取协议:邮件发送协议用于用户代理向邮件服务器发送邮件或在邮件服务器之间发送邮件,如SMTP;邮件读取协议用于用户代理从邮件服务器读取邮件,如POP3。
收发过程
- ①发信人调用用户代理来撰写和编辑要发送的邮件。用户代理用SMTP把邮件传送给发送端邮件服务器。
- ②发送端邮件服务器将邮件放入邮件缓存队列中,等待发送。
- ③运行在发送端邮件服务器的SMTP客户进程,发现邮件缓存中有待发送的邮件,就向运行在接收端邮件服务器的SMTP服务器进程发起建立TCP连接。
- ④TCP连接建立后,SMTP客户进程开始向远程SMTP服务器进程发送邮件。当所有待发送邮件发完后,SMTP就关闭所建立的TCP连接。
- ⑤运行在接收端邮件服务器中的SMTP服务器进程收到邮件后,将邮件放入收信人的用户邮箱,等待收信人在方便时进行读取。
- ⑥收信人打算收信时,调用用户代理,使用POP3(或IMAP)协议将自己的邮件从接收端邮件服务器的用户邮箱中取回(如果邮箱中有来信的话)。
6.4.2 SMTP和POP3
SMTP(简单邮件传输协议)
简单邮件传输协议(SMTP)是一种提供可靠且有效的电子邮件传输协议,它控制两个相互通信的SMTP进程交换信息。
采用客户/服务器方式,发送方为客户,接收方为服务器;TCP连接,端口号为25。
负责发送邮件的SMTP进程就是SMTP客户,负责接收邮件的进程就是SMTP服务器。
SMTP规定了14条命令(几个字母)和21种应答信息(三位数字代码+简单文字说明)
SMTP分为以下三个阶段:
建立连接
发件人邮件发送到发送方邮箱服务器的缓存中,SMTP客户定时扫描邮件缓存。
扫描发现有邮件,使用SMTP熟知端口号(25)与接收方邮件服务器的SMTP服务器建立TCP连接。
建立连接后,接收方SMTP服务器发出”220 Service ready(服务就绪)”。
SMTP客户向SMTP服务器发送”HELO命令”,附上发送方的主机名。
SMTP服务器若有能力接收邮件,回答”250 OK”;否则,回答”421 Service not available”
SMTP不使用中间的邮件服务器。TCP连接总是在发送方和接收方这两个邮件服务器之间直接建立。
邮件传输
1
2
3
4
5
6
7
8
9发送方:MAIL FROM:<send@123.com> //使用MAIL命令,附上发件人地址,开始邮件的传送
接收方:250 OK/451(452、200) //SMTP服务器回复,是否已经准备好接收邮件(是/否)
发送方:RCPT TO:<receive@456.com> //SMTP客户端回复一个或多个RCPT命令,确认用户是否接收
接收方:250 OK/550 No such user here //SMTP服务器确认是否接收
发送方:DATA //SMTP客户表示要开始传输邮件内容
接收方:354 start mail input;end with <CR><LF>.<CR><LF> //SMTP服务器同意传输并用<CRLF>.<CRLF>回车换行表示邮件内容的结束。
发送方:date... //开始传输邮件内容
接收方:250 OK //接收结束
12345678连接释放
邮件发完,SMTP客户发送QUIT命令,SMTP服务器返回“221”,表示同意释放TCP连接。
缺点:
- SMTP不能传送可执行文件或者其他二进制对象。
- SMTP仅限于传送7位ASCII码,不能传送其他非英语国家的文字。
- SMTP服务器会拒绝超过一定长度的邮件。
POP3(邮局协议)
邮局协议(Post Office Protocol,POP)是一个非常简单但功能有限的邮件读取协议。
POP3采用的是**“拉”(Pull)的通信方式,当用户读取邮件时,用户代理向邮件服务器发出请求,“拉”取用户邮箱中的邮件**。
使用客户/服务器,TCP连接,端口110。
工作方式:
- 下载并保留:用户从邮件服务器上读取邮件后,邮件依然会保存在邮件服务器上,用户可再次从服务器上读取该邮件。
- 下载并删除:邮件一旦被读取,就被从邮件服务器上删除,用户不能再次从服务器上读取。
IMAP(因特网报文存取协议)
IMAP协议比POP协议复杂。是一种复杂的邮件读取协议。
客户/服务器,TCP连接,端口号993
IMAP为用户提供了创建文件夹、在不同文件夹之间移动邮件及在远程文件夹中查询邮件等联机命令,为此IMAP服务器维护了会话用户的状态信息。
IMAP的另一特性是允许用户代理只获取报文的某些部分。当用户PC上的IMAP客户程序打开IMAP服务器的邮箱时,用户可以看到邮箱的首部,若用户需要打开某个邮件,该邮件才上传到用户的计算机上。
IMAP允许用户在多个客户端上管理同一个邮箱;IMAP可以访问服务器上的所有文件夹;IMAP可以实现邮件的部分下载,即只下载邮件的标题或正文。
6.4.3 电子邮件格式与MIME
电子邮件格式
电子邮件分为信封和内容两大部分,邮件内容又分为首部和主体两部分。
RFC822 规定了邮件首部格式,而邮件的主体内容用户自由撰写。邮件系统自动将邮件信息提取到信封上。
邮件内容首部包含一些首部行,每个首部行由 关键字 : 值 关键字:值 关键字:值 组成。主要关键字有 To 和 Subject 。
To:是必需的关键字,后面填入一个或多个收件人的电子邮件地址。地址规定 收件人邮箱名 @ 主机域名 收件人邮箱名@主机域名 收件人邮箱名@主机域名,如 a b c @ 123. c o m abc@123.com abc@123.com,abc在123.com必须是唯一的。
Subject:是可选关键字,邮件的主题。它反映了邮件的主要内容。
From:必需关键字,由邮箱系统自动填入。
主体与首部由一个空行进行分割。典型邮件格式如下。
多用途网际邮件扩充(MIME)
由于SMTP只能传送ASCII码邮件,为了传送其他国家文字字符,提出了多用途网际邮件扩充(MIME)。
MIME并未改动SMTP或取代它。MIME的意图是继续使用目前的格式,但增加了邮件主体的结构,并定义了传送非ASCII码的编码规则。主要包括以下三部分:
- 5个新的邮件首部字段,包括MIME版本、内容描述、内容标识、传送编码和内容类型。
- 定义了许多邮件内容的格式,对多媒体电子邮件的表示方法进行了标准化。
- 定义了传送编码,可对任何内容格式进行转换,而不会被邮件系统改变。
6.5 万维网(WWW)
6.5.1 WWW的概念与组成结构
万维网(World Wide Web,WWW)是一个分布式、联机式的信息存储空间,在这个空间中:一样有用的事物称为一样“资源”,并由一个全域**“统一资源定位符”(URL)标识。这些资源通过超文本传输协议(HTTP)**传送给使用者,而后者通过单击链接来获取资源。
万维网的内核部分是由三个标准构成的:
- 统一资源定位符(URL):负责标识万维网上的各种文档,并使每个文档在整个万维网的范围内具有唯一的标识符URL。
- 超文本传输协议(HTTP):一个应用层协议,它使用TCP连接进行可靠的传输,HTTP是万维网客户程序和服务器程序之间交互所必须严格遵守的协议。
- 超文本标记语言(HTML):一种文档结构的标记语言,它使用一些约定的标记对页面上的各种信息(包括文字、声音、图像、视频等)、格式进行描述。
URL是对从因特网上得到的资源的位置和访问方法的一种简洁表示。一般形式如下:
< 协议 > : / / < 主机 > : < 端口 > / < 路径 > <协议>://<主机>:<端口>/<路径> <协议>://<主机>:<端口>/<路径>- <协议>指用什么协议来获取万维网文档,常见的协议有http、ftp等
- <主机>是存放资源的主机在因特网中的域名或IP地址
- <端口>和<路径>有时可省略。在URL中不区分大小写。
这里省略了默认的端口号80。
万维网以客户/服务器方式工作。浏览器是在用户主机上的万维网客户程序,而万维网文档所驻留的主机则运行服务器程序,这台主机称为万维网服务器。工作流程如下:
- 1)Web用户使用浏览器(指定URL)与Web服务器建立连接,并发送浏览请求。
- 2)Web服务器把URL转换为文件路径,并返回信息给Web浏览器。
- 3)通信完成,关闭连接。
6.5.2 超文本传输协议(HTTP)
HTTP协议定义了浏览器(万维网客户进程)怎样向万维网服务器请求万维网文档,以及服务器怎样把文档传送给浏览器。
基于客户/服务器模式,基于TCP传输,默认80端口号。
HTTP的操作过程
浏览器要访问WWW服务器时,首先要完成对WWW服务器的域名解析。一旦获得了服务器的P地址,浏览器就通过TCP向服务器发送连接建立请求。
- 1)浏览器分析链接指向页面的URL(http://www.tsinghua.edu.cn/chn/index.htm)。
- 2)浏览器向DNS请求解析www.tsinghua.edu.cn的IP地址。
- 3)域名系统DNS解析出清华大学服务器的IP地址。
- 4)浏览器与该服务器建立TCP连接(默认端口号为80)。
- 5)浏览器发出HTTP请求取出文件命令:GET/chn/index.htm。
- 6)服务器通过HTTP响应把文件index.htm发送给浏览器。
- 7)释放TCP连接。
- 8)浏览器解释文件index.htm,并将Web页显示给用户。
HTTP的特点
HTTP是无连接的
HTTP基于TCP连接,用来保证可靠传输,但本身是无连接的。也就是通信的双方在交换HTTP报文之前不需要先建立HTTP连接。
HTTP是无状态的
同一个客户第二次访问同一个服务器上的页面时,服务器的响应与第一次被访问时的相同。因为服务器并不记得曾经访问过的这个客户,也不记得为该客户曾经服务过多少次。
但是在实际工作中,一些万维网站点常常希望能够识别用户
Cookie:是存储在用户主机中的文本文件,记录一段时间内某用户(使用识别码识别,如“123456”)的访问记录。 提供个性化服务。
连接方式
非持久连接
对于非持久连接,每个网页元素对象(如JPEG图形、Flash等)的传输都需要单独建立一个TCP连接。
请求 w e b 文档所需时间 = 传输时间 + 2 R T T 请求web文档所需时间=传输时间+2RTT 请求web文档所需时间=传输时间+2RTT
请求一个万维网文档所需的时间是该文档的传输时间(与文档大小成正比)加上两倍往返时间RTT(一个RTT用于TCP连接,另一个RTT用于请求和接收文档)。 每个对象引用都导致2×RTT的开销,此外每次建立新的TCP连接都要分配缓存和变量,使万维网服务器的负担很重。
持久连接
持久连接是指万维网服务器在发送响应后仍然保持这条连接,使同一个客户(浏览器)和该服务器可以继续在这条连接上传送后续的HTTP请求和响应报文。
持久连接又分为非流水线和流水线两种方式。
非流水线方式:客户在收到前一个响应后才能发出下一个请求,服务器发送完一个对象后,其TCP连接就处于空闲状态,浪费了服务器资源。
流水线方式:客户每遇到一个对象引用就立即发出一个请求,因而客户可以逐个地连续发出对各个引用对象的请求。HTTP/1.1的默认方式。
如果所有的请求和响应都是连续发送的,那么所有引用的对象共计经历1个RTT延迟,而不是像非流水线方式那样,每个引用都必须有1个RTT延迟。这种方式减少了TCP连接中的空闲时间,提高了效率。
HTTP的报文结构
HTTP是面向文本的(Text-Oriented),因此报文中的每个字段都是一些ASCII码串,并且每个字段的长度都是不确定的。有两类HTTP报文:
- 请求报文:从客户向服务器发送的请求报文。
- 响应报文:从服务器到客户的回答。
开始行:用于区分是请求报文还是响应报文。在请求报文中的开始行称为请求行,而在响应报文中的开始行称为状态行。开始行的三个字段之间都以空格分隔,最后的“CR”和“LF”分别代表**“回车”和“换行”**。
请求报文的“请求行”有三个内容:方法、请求资源的URL及HTTP的版本。其中,“方法”是对所请求对象进行的操作,这些方法实际上也就是一些命令。
方法(操作) 意义 GET 请求读取由URL标识的信息 HEAD 请求读取由URL标识的信息的首部 POST 给服务器添加信息(如注释) PUT 在指明的URL下存储一个文档 DELETE 删除指明的URL所标志的资源 CONNECT 用于代理服务器 首部行:用来说明浏览器、服务器或报文主体的一些信息。首部可以有几行,但也可以不使用。
在每个首部行中都有首部字段名和它的值,每一行在结束的地方都要有**“回车”和“换行”。整个首部行结束时,还有一空行将首部行和后面的实体主体**分开。
实体主体:在请求报文中一般不用这个字段,而在响应报文中也可能没有这个字段。
状态码:状态行包括三项内容,即HTTP的版本,状态码,以及解释状态码的简单短语。
- 1xx:表示通知信息的,如请求收到了或正在处理。
- 2xx:表示成功,如接受或知道了。
- 3xx:表示重定向,如要完成请求还必须采取进一步的行动。
- 4xx:表示客户的差错,如请求中有错误的语法或不能完成。
- 5xx:表示服务器的差错,如服务器失效无法完成请求。
下面三种状态行在响应报文中是经常见到的:
下面是一个完整的HTTP请求报文的例子:
在请求行使用了相对URL(即省略了主机的域名)是因为下面的首部行(第2行)给出了主机的域名。第3行是告诉服务器不使用持续连接,表示浏览器希望服务器在传送完所请求的对象后即关闭TCP连接。这个请求报文没有实体主体。
若请求的网页转移到了一个新的地址,则响应报文的状态行和一个首部行就是下面的形式:
常见应用层协议小结:
应用程序 | FTP数据 | FTP控制 | TELNET | SMTP | DNS | TFTP | HTTP | POP3 | SNMP |
---|---|---|---|---|---|---|---|---|---|
使用协议 | TCP | TCP | TCP | TCP | UDP | UDP | TCP | TCP | UDP |
熟知端口号 | 20 | 21 | 23 | 25 | 53 | 69 | 80 | 110 | 161 |
第3章 MongoDB数据库操作
3.1 MongoDB部署
通过访问MongoDB官网进入MongoDB下载页面。
Version:指定MongoDB版本,MongoDB的版本分为稳定版和开发板,本次安装使用稳定版4.2。
提示:版本的选择:
MongoDB的版本命名规范如:x.y.z;
y为奇数时表示当前版本为开发版,如:1.5.2、4.1.13;
y为偶数时表示当前版本为稳定版,如:1.6.3、4.0.10;
z是修正版本号,数字越大越好。
GUI工具-NoSQLBooster for MongoDB
当然你可以用可视化界面进行连接数据库。比如Studio 3T、NoSQL Manager for MongoDB、NoSQLBooster for MongoDB等GUI工具。
这里推荐使用NoSQLBooster for MongoDB(破解方法在群文件可下载)
- 首先再次启动mongod服务
1 | [root@localhost ~]# mongod -f /usr/local/mongodb/standalone/mongod.conf |
- 打开NoSQLBooster,新建单节点服务器配置并测试连接是否可通。
3.2 数据库操作
新建数据库、查看数据库、删除数据库
选择和创建数据库的语法格式:
use 数据库名称
如果数据库不存在则自动创建,例如,以下语句创建 spitdb 数据库:
use articledb
查看有权限查看的所有的数据库命令:
show dbs 或show databases
注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。
查看当前正在使用的数据库命令:
db
MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
- admin:从权限的角度来看,这是”root”数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local:(集群和分片时用)这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
MongoDB 删除数据库的语法格式如下:
db.dropDatabase()
提示:主要用来删除已经持久化的数据库
3.3 集合操作
创建集合、删除集合
集合,类似关系型数据库中的表。
可以显示的创建,也可以隐式的创建。
集合的显式创建:
db.createCollection(name)
参数说明:
name: 要创建的集合名称
例如:创建一个名为 mycollection 的普通集合。
db.createCollection("mycollection")
查看当前库中的表:show tables命令
show collections 或show tables
集合的隐式创建:
当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合 详见 文档的插入 章节。
提示:通常我们使用隐式创建文档即可。
集合的删除:
db.collection.drop() 或db.集合.drop()
返回值
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
例如:要删除mycollection集合
db.mycollection.drop()
3.4 文档的插入、更新与删除操作
文档插入
文档(document)的数据结构和 JSON 基本一样。所有存储在集合中的数据都是 BSON 格式。
insert()和save()方法的区别在于:
若使用insert()方法插入文档时,集合中已存在该文档,则会报错。
若使用save()方法插入文档时,集合中已存在该文档,则会覆盖。
(1)单个文档插入
使用insert() 或 save() 方法向集合中插入文档,语法如下:
1 | db.collection.insert( |
要向comment的集合(表)中插入一条测试数据:
1 | db.comment.insert({"articleid":"100000","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Rose","createdatetime":new Date(),"likenum":NumberInt(10),"state":null}) |
提示:
1)comment集合如果不存在,则会隐式创建
2)mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。
3)插入当前日期使用 new Date()
4)插入的数据没有指定 _id ,会自动生成主键值
5)如果某字段没值,可以赋值为null,或不写该字段。
执行后,如下,说明插入一个数据成功了。WriteResult({ “nInserted” : 1 })
注意:
文档中的键/值对是有序的。
文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
MongoDB区分类型和大小写。
MongoDB的文档不能有重复的键。
文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
文档键命名规范:
键不能含有\0 (空字符)。这个字符用来表示键的结尾。
.和$有特别的意义,只有在特定环境下才能使用。
以下划线”_”开头的键是保留的(不是严格要求的)。
(2)批量插入
1 | db.collection.insertMany( |
【示例】
批量插入多条文章评论:
1 | db.comment.insertMany([ |
提示:
插入时指定了 _id ,则主键就是该值。
如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。如(掌握):
1 | try { |
文档更新
(1)覆盖的修改
如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:
1 | // 先查询当前数据库中的数据 |
这是原本的数据。
执行后,我们会发现,这条文档除了likenum字段其它字段都不见了,
(2)局部修改
为了解决这个问题,我们需要使用修改器$set来实现,命令如下:
我们想修改_id为2的记录,点赞数为889,输入以下语句:
1 | db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}}) |
(3)批量的修改
更新所有用户为 1003 的用户的昵称为 张三 。
1 | //默认只修改第一条数据 |
1 | //修改所有符合条件的数据 |
提示:如果不加后面的参数,则只更新符合条件的第一条记录
(4)列值增长的修改
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。
需求:对3号数据的点赞数,每次递增1
1 | db.comment.update({_id:"3"},{$inc:{likenum:NumberInt(1)}}) |
动手操作
将键contect的值由
“研究表明,刚烧开的水千万不能喝,因为烫嘴。”
更新为
“喝水增加了尿量,能使有害物质及时排出体内”,具体命令如下。
1 | db.comment.update({"content":"研究表明,刚烧开的水千万不能喝,因为烫嘴。"},{$set:{"content":"喝水增加了尿量,能使有害物质及时排出体内"}},{multi:true}) |
文档删除
删除文档的语法结构:
db.集合名称.remove(条件)
1 | db.comment.remove({userid:"1003"}) |
删除集合comment中键nickname为“爱德华”的文档,具体命令如下。
1 | db.comment.remove({"nickname":"爱德华"}) |
查看集合中所有文档,验证文档是否删除成功,具体命令如下。
1 | db.comment.find() |
删除集合comment中全部文档,具体命令如下。
1 | db.comment.remove({}) |
再次查看集合中所有文档,验证文档是否全部删除,具体命令如下。
1 | db.comment.find() |
3.5 文档查询
3.5.1 文档的简单查询
(1)查询所有
如果我们要查询spit集合的所有文档,我们输入以下命令
1 | db.comment.find() |
或
1 | db.comment.find({}) |
这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段,MongoDB会自动创建,其类型是ObjectID类型。
如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也可以是MongoDB支持的任意类型。
如果我想按一定条件来查询,比如我想查询userid为1003的记录,怎么办?很简单!只 要在find()中添加参数即可,参数也是json格式,如下:
1 | db.comment.find({userid:'1003'}) |
如果你只需要返回符合条件的第一条数据,我们可以使用findOne命令来实现,语法和find一样。
如:查询用户编号是1003的记录,但只最多返回符合条件的第一条记录:
1 | db.comment.findOne({userid:'1003'}) |
(2)投影查询(Projection Query):
如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。
如:查询结果只显示 _id、userid、nickname :
1 | db.comment.find({userid:"1003"},{userid:1,nickname:1}) |
默认 _id 会显示。
如:查询结果只显示 、userid、nickname ,不显示 _id :
1 | db.comment.find({userid:"1003"},{userid:1,nickname:1,_id:0}) |
再例如:查询所有数据,但只显示 _id、userid、nickname :
1 | db.comment.find({},{userid:1,nickname:1}) |
3.5.2 文档更多查询
统计查询
使用count()方法
【示例】
(1)统计所有记录数:
统计comment集合的所有的记录数:
1 | db.comment.count() |
(2)按条件统计记录数:
例如:统计userid为1003的记录条数
1 | db.comment.count({userid:"1003"}) |
提示:
默认情况下 count() 方法返回符合条件的全部记录条数。
文档的分页列表查询
可以使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据。
如果你想返回指定条数的记录,可以在find方法后调用limit来返回结果(TopN),默认值20,例如:
1 | db.comment.find().limit(3) |
skip方法同样接受一个数字参数作为跳过的记录条数。(前N个不要),默认值是0
1 | db.comment.find().skip(3) |
分页查询:需求:每页2个,第二页开始:跳过前两条数据,接着值显示3和4条数据
1 | //第一页 |
文档的排序查询
sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
例如:
对userid降序排列,并对访问量进行升序排列
1 | db.comment.find().sort({userid:-1,likenum:1}) |
对userid降序,对点赞数升序,查询结果按userid和likenum的条件限制
1 | db.comment.find({},{userid:1,likenum:1}).sort({userid:-1,likenum:1}) |
提示:
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。
文档的正则复杂条件查询
MongoDB的模糊查询是通过正则表达式的方式实现的。格式为:
db.collection.find({field:/正则表达式/})
或
db.集合.find({字段:/正则表达式/})
提示:正则表达式是js的语法,直接量的写法。
例如,我要查询评论内容包含“开水”的所有文档,代码如下:
1 | db.comment.find({content:/开水/}) |
如果要查询评论的内容中以“专家”开头的,代码如下:
1 | db.comment.find({content:/^专家/}) |
文档的比较查询
<, <=, >, >= 这个操作符也是很常用的,格式如下:
db.集合名称.find({ “field” : { $gt: value }}) // 大于: field > value
db.集合名称.find({ “field” : { $lt: value }}) // 小于: field < value
db.集合名称.find({ “field” : { $gte: value }}) // 大于等于: field >= value
db.集合名称.find({ “field” : { $lte: value }}) // 小于等于: field <= value
db.集合名称.find({ “field” : { $ne: value }}) // 不等于: field != value
示例:查询评论点赞数量大于700的记录
1 | db.comment.find({likenum:{$gt:NumberInt(700)}}) |
文档的包含查询
包含使用$in操作符。 示例:查询评论的集合中userid字段包含1003或1004的文档
1 | db.comment.find({userid:{$in:["1003","1004"]}}) |
不包含使用$nin操作符。 示例:查询评论集合中userid字段不包含1003和1004的文档
1 | db.comment.find({userid:{$nin:["1003","1004"]}}) |
文档的条件连接查询
我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。(相当于SQL的and)格式为:
$and:[ { },{ },{ } ]
示例:查询评论集合中likenum大于等于700 并且小于2000的文档:
1 | db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]}) |
如果两个以上条件之间是或者的关系,我们使用操作符进行关联,与前面and的使用方式相同格式为:
$or:[ { },{ },{ } ]
示例:查询评论集合中userid为1003,或者点赞数小于1000的文档记录
1 | db.comment.find({$or:[ {userid:"1003"} ,{likenum:{$lt:1000} }]}) |
小结
1 | 选择切换数据库:use articledb |
3.6 聚合操作
3.6.1 常见管道操作符
聚合管道操作是将文档在一个管道处理完毕后,把处理的结果传递给下一个管道进行再次处理。聚合管道是使用不同的管道阶段操作器进行不同聚合操作,管道阶段操作器也可称为管道操作符,常见管道操作符如下表。
常见管道操作符 | 相关说明 |
---|---|
$group | 将集合中的文档进行分组,便于后续统计结果 |
$limit | 用于限制MongoDB聚合管道返回的文档数 |
$match | 用于过滤数据,只输出符合条件的文档 |
$sort | 将输入的文档先进行排序,再输出 |
$project | 用于修改输入文档的结构(增加、删除字段等)和名称 |
$skip | 在聚合管道中跳过指定数量的文档,并返回剩余的文档 |
使用$group操作符,将集合comment中的文档按userid进行分组,具体命令如下。
1 | db.comment.aggregate([{$group:{"_id":"$userid"}}]).pretty() |
使用$limit操作符,展示集合comment中前三个文档,具体命令如下。
1 | db.comment.aggregate({$limit:3}).pretty() |
使用$match操作符,将集合comment中键nickname的值为凯撒的文档查询出来,具体命令如下。
1 | db.comment.aggregate([{$match: {nickname:"凯撒"}}]) |
使用$sort操作符,将集合comment中的文档按照键likenum的值进行降序排序,具体命令如下。
1 | db.comment.aggregate([{$sort: {likenum:-1}}]).pretty() |
使用$project操作符,展示集合comment中的文档,并且文档均不包含字段_id,具体命令如下。
1 | db.comment.aggregate([{$project:{"_id":0}}]).pretty() |
使用$project操作符,展示集合comment中的_id为5、6的文档,具体命令如下。
1 | db.comment.aggregate({$skip:4}).pretty() |
3.6.2 常见管道表达式
管道阶段操作器的值被称为管道表达式,并且每个管道表达式都是一个文档结构,由字段名称、字段值和管道表达式组成。常见的管道表达式如下表。
常见管道表达式 | 相关说明 |
---|---|
$sum | 用于计算总和 |
$avg | 计算平均值 |
$min | 获取集合中所有文档对应值的最小值 |
$max | 获取集合中所有文档对应值的最大值 |
$push | 用于在结果文档中插入值到一个数组中 |
$first | 获取分组文档中的第一个文档 |
$last | 获取分组文档中的最后一个文档 |
切换的articledb数据库,向集合product中插入五个文档,具体命令如下。
1 | db.product.insertMany([ |
使用$avg表达式,将集合product中的文档按类型type进行分组并计算各个分组的价格price总和,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","price":{$sum:"$price"}}}]).pretty() |
使用$avg表达式,将集合product中的文档按类型type进行分组,并计算各个分组的价格price平均值,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","price":{$avg:"$price"}}}]).pretty() |
使用$min表达式,将集合product中的文档按类型type进行分组,并计算各个分组中价格price最小值,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","price":{$min:"$price"}}}]).pretty() |
使用$max表达式,将集合product中的文档按类型type进行分组,并计算各个分组中价格price最大值,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","price":{$max:"$price"}}}]).pretty() |
使用$push表达式,将集合product中的文档按类型type进行分组,并将各个分组的产品插入到一个数组tags中,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","tags":{$push:"$name"}}}]).pretty() |
使用$first表达式,将集合product中的文档按类型type进行分组,并获取各个分组中第一个产品,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","product":{$first:"$name"}}}]).pretty() |
使用$last表达式,将集合product中的文档按类型type进行分组,并获取各个分组中最后一个产品,具体命令如下。
1 | db.product.aggregate([{$group:{"_id":"$type","product":{$last:"$name"}}}]).pretty() |
3.6.3 Map-Reduce操作
MongoDB提供Map-Reduce操作来进行聚合操作。通常,Map-Reduce操作有两个阶段,即Map和Reduce阶段,其中Map阶段是对集合中的每个输入文档进行处理,处理结束后输出一个或多个结果,Reduce阶段是将Map阶段输出的一个或多个结果进行合并输出。
①query阶段,查询集合orders中字段status为A的文档
②map阶段,按照字段cust_id进行分组,将字段cust_id相同的amount值放到一个数组中
③reduce阶段,通过函数sum对每组的amount值进行求和
④output阶段,将结果输出到集合order_totals中
1 | db.COLLECTION_NAME.mapReduce( |
示例:
查询集合comment中字段state为1的文档,按照字段nickname对文档进行分组,计算出每个评论者的评论条数。
1 | db.comment.mapReduce( |
!
查询结果集合comment_total中的结果数据。
1 | db.comment_total.find() |
3.7 使用索引优化查询
3.7.1 索引概述
索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。
索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。官网文档:https://docs.mongodb.com/manual/indexes/
了解:
MongoDB索引使用B树数据结构(确切的说是B-Tree,MySQL是B+Tree)。多路动态平衡树,简称B-Tree,效率高,尤其是可以最大提高磁盘io效率,所以大部分数据库的存储引擎都用b-tree作为索引的数据存储结构
1.单字段索引
MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,因此被称为单字段索引(Single Field Index)。默认情况下,MongoDB中所有集合在“_id”字段上都有一个索引,用户也可以根据自己的需求添加额外索引来支持重要的查询和操作。由于MongoDB可以从任何方向遍历索引,因此对于单个字段索引和排序操作来说,索引项的排序顺序(即升序或降序)并不重要。
在集合collection中的字段score上创建了一个索引,并指定其为有序。
2.复合索引
MongoDB除了支持单字段索引外,还支持复合索引。所谓复合索引,就是包含多个字段的索引,一个复合索引最多可以包含31个字段。需要注意的是,若某字段属于哈希索引,则这时复合索引就不能包括该字段。
复合索引是由{userid:1,score:-1}组成的,因此复合索引首先按字段userid通过ascii码的形式进行升序排序,然后在每个字段userid的值内,按照score降序排序。
3.7.2 索引操作
(1)单字段索引
1 | //对 userid 字段建立索引,参数1:按升序创建索引 |
(2)复合索引
1 | //对 userid 和 nickname 同时建立复合(Compound)索引 |
(3) 索引的移除
说明:可以移除指定的索引,或移除所有索引
- 指定索引的移除
【示例】
删除 comment 集合中 userid 字段上的升序索引:
1 | db.comment.dropIndex({userid:1}) |
查询
1 | db.comment.getIndexes() |
所有索引的移除
【示例】1
2
3
4
5//删除集合中所有索引。
db.comment.dropIndexes()
//查询
db.comment.getIndexes()
3.8 使用Java操作MongoDB
3.8.1 搭建Java环境
JDK的卸载
删除JDK的文件夹
1、在控制面板–程序中,卸载java8的旧版本
2、然后找到安装路径后,直接删除
删除环境变量的配置
此电脑–高级系统设置–环境变量–删除JAVA_HOME
删除Path中关于java的目录
测试是否卸载成功
WIN + R 打开CMD,输入java -version 测试是否卸载成功。
安装新版的JDK
1、百度搜索JDK 8
2、同意协议3、下载电脑对应的版本
4、双击安装JDK
5、记住安装路径(避免使用中文路径)
6、配置环境变量
1.此电脑–右键–属性–高级系统设置–环境变量
2.环境变量–>JAVA_HOME
3.配置Path变量
新建 %JAVA_HOME%\bin
新建 %JAVA_HOME%\jre\bin
4.测试是否成功
CMD中,输入java -version
maven的安装
访问maven官网下载Windows系统下的Maven安装包,本书下载的是maven 3.8.3版本,即apache-maven-3.8.3-bin.zip安装包。
将Maven安装路径下的bin目录添加到系统环境变量的Path变量中,这里添加的C:\Environment\Maven\apache-maven-3.8.3\bin。
Maven环境变量配置完成后,在Windows的DOS窗口执行“mvn -version”命令,查看Maven是否安装配置成功。
修改Maven配置文件settings.xml,该文件位于Maven安装路径下的conf文件夹内,向配置文件中添加本地仓库路径和远程仓库路径,需要注意的是本地仓库路径需要提前创建。
本地仓库
远程仓库(可配阿里云-自行百度)
1 | <mirrors> |
3.8.2 基于Java API操作MongoDB
idea项目建立
配置IDEA工具,在IDEA安装完成后的界面,单击“Configure”→“Settings”→“Build,Execution,Deployment”→“Build Tools”→“Maven”,将Maven添加至IDEA工具中。
配置IDEA工具,在IDEA安装完成后的界面,“Configure”→“Structure for New Projects”→“Project”,将jdk添加至IDEA工具中。
打开IDEA工具,单击“Create New Project”→“Maven”,选择创建一个Maven项目。
添加Maven项目的名称和指定项目的存储路径。
完成Maven项目的创建。
在项目article中配置pom.xml文件,引入MongoDB相关的依赖和单元测试的依赖。
3.9 项目实训 文章评论
3.9.1 需要实现
以下功能:
1)基本增删改查API
2)根据文章id查询评论
3)评论点赞
数据库:articledb
3.9.2 文章微服务模块搭建
(1)搭建项目工程article,并设置pom.xml引入依赖:
1 |
|
(2)在article\src\main\resources下创建文件application.yml
1 | spring: |
(3)创建启动类
在article\src\main\java下创建类cn.itcast.article.ArticleApplication(此处命名方法使用到包机制)
1 | package cn.itcast.article; |
(4)启动项目,看是否能正常启动,控制台没有错误。
3.9.3 文章评论实体类的编写
在article\src\main\java下创建实体类,创建包cn.itcast.article,包下建包po用于存放实体类,创建实体类
cn.itcast.article.po.Comment
1 | package cn.itcast.article.po; |
3.9.4 文章评论的基本增删改查
(1)创建数据访问接口 cn.itcast.article包下创建dao包,包下创建接口
cn.itcast.article.dao.CommentRepository
1 | package cn.itcast.article.dao; |
(2)创建业务逻辑类 cn.itcast.article包下创建service包,包下创建类
cn.itcast.article.service.CommentService
1 | package cn.itcast.article.service; |
(3)新建Junit测试类,测试保存和查询所有:
在article\src\test\java下新建测试类cn.itcast.article.service.CommentServiceTest
1 | package cn.itcast.article.service; |
添加一条测试数据
根据上级ID查询文章评论的分页列表
插入一条测试数据
1 | db.comment.insert([{"parentid":"3","nickname":"张三"}]) |
MongoTemplate实现评论点赞