[奶妈の白嫖站]计算机网络 大作业 IP分组转发 C++/VS

[奶妈の白嫖站]计算机网络 大作业 IP分组转发 C++/VS

奶妈の白嫖站

本程序以ppt上的例题图为例,书pdf151页上也有图和算法讲解
在这里插入图片描述
运行截图
在这里插入图片描述
程序代码 :本程序使用VS2015编写,支持中文变量,如软件不支持中文变量可使用wps进行批量查找替换(注意有些词组嵌套:如 路由表、路由表记录 等)

/*本程序使用VS2015编写,支持中文变量,如软件不支持中文变量可使用wps进行批量查找替换(注意有些词组嵌套:如 路由表、路由表记录 等)*/
/*本程序以ppt上的例题图为例,书pdf151页上也有图和算法讲解*/
#include<iostream>
#include<string>
using namespace std;
#define x 5  //假设路由表最多存x行路由表记录
#define y 5  //假设最多有y个路由器
/***************建立 路由表 和 路由表记录 结构体***************/
struct 路由表记录
{
	string 目的网络地址 = "0";  //0用于打印时判断截止
	string 子网掩码;
	string 下一跳;
	int 接口号;  //转发到路由器R[接口号]
};
struct 路由表
{
	路由表记录 info[x];  //设每个路由表最多有n行路由表记录
}R[y];  //相当于直接:路由表 R[y];
/***************打印 路由表 和 路由表记录 信息***************/
void 打印路由表(路由表 R)
{
	cout << "目的网络地址\t子网掩码\t下一跳\t\t接口号\n";
	for (int i = 0; i < x && R.info[i].目的网络地址 != "0"; i++)
	{
		cout << R.info[i].目的网络地址 << "\t" << R.info[i].子网掩码 << "\t" << R.info[i].下一跳 << "\t\t" << "R" << R.info[i].接口号+1 << "\n";

	}
}
/***********内部手动部分定义 路由表 和 路由表记录 信息***********/
void 输入部分路由表(路由表 R[])
{
	R[0].info[0].目的网络地址 = "128.30.33.0";
	R[0].info[0].子网掩码 = "255.255.255.128";
	R[0].info[0].下一跳 = "接口0";
	R[0].info[0].接口号 = 0;

	R[0].info[1].目的网络地址 = "128.30.33.128";
	R[0].info[1].子网掩码 = "255.255.255.128";
	R[0].info[1].下一跳 = "接口1";
	R[0].info[1].接口号 = 0;

	R[0].info[2].目的网络地址 = "128.30.36.0";
	R[0].info[2].子网掩码 = "255.255.255.0";
	R[0].info[2].下一跳 = "R2";
	R[0].info[2].接口号 = 1;

	R[1].info[0].目的网络地址 = "128.30.33.128";
	R[1].info[0].子网掩码 = "255.255.255.128";
	R[1].info[0].下一跳 = "接口0";
	R[1].info[0].接口号 = 1;

	R[1].info[1].目的网络地址 = "128.30.36.0";
	R[1].info[1].子网掩码 = "255.255.255.0";
	R[1].info[1].下一跳 = "接口1";
	R[1].info[1].接口号 = 1;

	R[1].info[2].目的网络地址 = "128.30.33.0";
	R[1].info[2].子网掩码 = "255.255.255.128";
	R[1].info[2].下一跳 = "R1";
	R[1].info[2].接口号 = 0;
}
/***********制作 string地址 转 数组[4] 的工具函数***********/
void 字符串转数组(string address, int a[4])
{
	a[0] = a[1] = a[2] = a[3] = 0;
	int num = 0;  //num指向数组a[]位置,i指向字符串address位数
	int size = address.length();
	for (int i = 0; i < size; i++)
	{
		while (isdigit(address[i]))  //isdigit:如果是'0'-'9',则返回1
		{
			a[num] = a[num] * 10 + (address[i] - '0');
			i++;
		}
		num++;
	}
	if (num != 4)
	{
		cout << "格式不对,转换出错\n";
	}
}
/***********将 网络地址 和 子网掩码 相与***********/
string 相与(string ip1, string ip2)
{
	int a[4], b[4], c[4];
	字符串转数组(ip1, a);
	字符串转数组(ip2, b);
	for (int i = 0; i < 4; i++)
		c[i] = a[i] & b[i];
	char ip3[20];
	//sprintf_s:将数据格式化输出到字符串(不加"_s"会报错)
	sprintf_s(ip3, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]);
	string ip = ip3;
	return ip;
}
/****************ip分组转发(初次转发)****************/
void ip转发(string 源地址, string 目的地址, string 源掩码, int 路由器号)
{
	cout << "源地址:" << 源地址 << "\t源子网掩码:" << 源掩码 << "\t目的地址:" << 目的地址 << "\t路由器号:R" << 路由器号 <<endl;
	/****************(1)判断是否 直接交付****************/
	if (相与(源地址, 源掩码) == 相与(源掩码, 目的地址))
	{
		cout << "源主机和目的主机在同一个网络,直接交付\n";
		return;
	}
	else
		cout << "\n源主机和目的主机不在同一个网络,转到路由器R" << 路由器号 << "进行查找\n";
	/****************(2)为否时 查找路由器****************/
	int flag = 0;  //定义一个检测是否交付成功的标志位flag
	for (int i = 0; i < x; i++)
	{
		if (R[路由器号 - 1].info[i].目的网络地址 == 相与(R[路由器号 - 1].info[i].子网掩码, 目的地址))
		{
			if (R[路由器号 - 1].info[i].接口号 == 路由器号 - 1)
			{
				cout << "目的主机与路由器R" << 路由器号 << "直接相连,从" << R[路由器号 - 1].info[i].下一跳 << "直接交付\n";
				return;
			}
			else
			{
				cout << "目的主机与路由器R" << 路由器号 << "非直接相连,从" << R[路由器号 - 1].info[i].下一跳 << "转发数据报\n";
				/****************更新查找****************/
				int 新路由器号 = R[路由器号 - 1].info[i].接口号+1;
				ip转发(源地址, 目的地址, 源掩码, 新路由器号);  //仅替换新路由器号即可
				return;
			}
		}
		flag++;
	}
	if (flag = x)
		cout << "在已知的路由器表中没有找到交付地址\n";
}
int main()
{
	输入部分路由表(R);
	/***********输出已定义值的路由表***********/
	for (int i = 0; i < y && R[i].info[0].目的网络地址 != "0"; i++)
	{
		cout << "——————————" << "路由表" << i + 1 << "的已知信息——————————\n";
		打印路由表(R[i]);
	}
	/****************ip分组转发****************/
	string 源地址, 目的地址, 源掩码;
	int 路由器号;
	cout << "请输入源地址:";
	cin >> 源地址;
	cout << "请输入源子网掩码:";
	cin >> 源掩码;
	cout << "请输入目的地址:";
	cin >> 目的地址;
	cout << "请输入本网络连接的路由器号R__:";
	cin >> 路由器号;
	ip转发(源地址, 目的地址, 源掩码, 路由器号);
	/***************结束程序***************/
	system("pause");  //获取一次回车,防止运行完瞬间退出
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44275036/article/details/106215920