计算机网络实验六-内部网关协议RIP
RIP协议基于Bellham-Ford(距离向量)算法的路由选择协议,RIP协议是最大的优点是简单,它将“距离”定义为:从一路由器到非直接连接的网络的距离所经过的路由器数加1,路由器到直接交付的网络距离可定义为1或0都可。
RIP协议的“距离”也称跳数,每经过一个路由器,跳数就加1,RIP认为好的路由就是它经过的路由器的数目少。RIP允许一条路径最多只包含15个路由器,当跳数为16时即为不可达,因此RIP只适用于小型互联网。
RIP协议特点:
1.仅和相邻路由器交换信息。
2.路由器交换的信息是当前本路由器所知道的所有信息,即当前自己的路由表。
3.按照经过固定的时间间隔交换信息
一般情况下,RIP协议可以收敛,当所有的路由器都得到正确的路由选择信息,即不论交换多少次,所有路由器的路由表都不再变化,该自治系统收敛。
#include <iostream>
#define MAX 100
#define MAX_DIS 16
using namespace std;
// 路由表
struct routertable{
int prps_idx; // 目的网络
int dis; // 距离
int nextHop; // 下一跳路由器
};
// 路由器
struct router{
int idx; // 序号
routertable rt[MAX]; // 路由表
int len; // 目前的路由表长度
};
// 邻近可达矩阵
int s[6][6] = {{0,1,1,1},{1,0,0,1,0,1},{1,0,0,0,1},{1,1,0,0,0,1},{0,0,1,0,0,1},{0,1,0,1,1,0}};
// 图初始化数据
int init[100][100] ={{1,1,0,2,1,0,3,1,0},{1,1,0,5,1,0},{3,1,0,4,1,0},{2,1,0,5,1,0},{4,1,0,6,1,0},{5,1,0,6,1,0}};
// 各路由器收敛速度
int count[6];
// 交换函数,a收到b的路由表信息,更新a路由表
int swap1(router* a, router* b, int& flag1) {
int flag = 0;
// 获取b路由表的长度 构造修改后的路由表cpb
int blen = b->len;
routertable* cpb = new routertable[blen];
for(int i = 0; i < blen; i++) {
cpb[i].prps_idx = b->rt[i].prps_idx;
// 距离 + 1
cpb[i].dis = b->rt[i].dis + 1;
// 下一跳全改成b路由表
cpb[i].nextHop = b->idx;
}
// 获取a路由表长度,根据cpb更新a路由表
int alen = a->len;
for(int i = 0; i < blen; i++) {
int f = 1;
for(int j = 0; j < alen; j++){
// 先判断是否存在该目的网络 不存在直接插入
if(a->rt[j].prps_idx == cpb[i].prps_idx) {
f = 0;
// 存在再判断下一跳是否相同 相同即更新
if(a->rt[j].nextHop == cpb[i].nextHop){
if(a->rt[j].dis != cpb[i].dis) {
flag1 = 1;
flag = 1;
}
a->rt[j] = cpb[i];
// 不同再判断距离,如果cpb小于a即更新
} else if (cpb[i].dis < a->rt[j].dis) {
flag1 = 1;
flag = 1;
a->rt[j] = cpb[i];
}
}
}
if(f) {
flag1 = 1;
flag = 1;
a->rt[a->len++] = cpb[i];
}
}
return flag;
}
int main() {
router* root = new router[6];
// 初始化各个路由器的路由表
for(int i = 0; i < 6; i++){
int j = 0;
root[i].len = 0;
while(init[i][j] != 0) {
int len = root[i].len;
root[i].idx = i + 1;
root[i].rt[len].prps_idx = init[i][j];
root[i].rt[len].dis = init[i][j+1];
root[i].rt[len].nextHop = init[i][j+2];
root[i].len += 1;
j += 3;
}
}
// 输出各路由器初始路由表
for(int i = 0; i < 6; i++){
cout << "路由器R" << i+1 << "的初始路由表:" << endl;
cout << "目的网络" << " " << "距离" << '\t' << "下一跳" << endl;
int j = 0;
while(j < root[i].len) {
cout << root[i].rt[j].prps_idx << '\t'<<" " << root[i].rt[j].dis << '\t' << root[i].rt[j].nextHop << endl;
j++;
}
}
// 每次让邻近路由器交换路由信息
// 终止条件为一个周期内没有路由表更新 一个周期为遍历一次s矩阵
int flag = 1;
while(flag) {
flag = 0;
for(int i =0;i<6;i++){
for(int j =0;j<6;j++){
int flag1 = 0;
if(s[i][j]) {
flag = swap1(&root[i],&root[j], flag1);
if (flag1) count[i]++;
}
}
}
}
for(int i =0;i<6;i++){
cout << "路由器R" << i+1 << "的最终路由表:" << endl;
cout << "目的网络" << " " << "距离" << '\t' << "下一跳" << endl;
int j = 0;
while(j < root[i].len) {
cout << root[i].rt[j].prps_idx << '\t'<<" " << root[i].rt[j].dis << '\t' << root[i].rt[j].nextHop << endl;
j++;
}
}
for(int i =0;i<6;i++){
cout << "路由器R" << i+1 << "的收敛速度:";
cout << count[i] << endl;
}
return 0;
}