⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exp3.cpp

📁 本程序实现了计算机网络中各种IP地址的转换,以及路由算法,欢迎下载
💻 CPP
字号:
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdio.h>

void changetodotdecimal(int (*a)[8])         //change to dotted decimal notation
{
	int *dot;
	dot=new int [4];
	for(int i=0;i<4;i++)
		dot[i]=0;
	
	 int temp=0;         //k refers to the weight pow(2,k)
	for(i=0;i<=3;i++)
	{
		int k=0;   
		for(int j=7;j>=0;j--)
		{
		
			temp=a[i][j]*pow(2,k);
			dot[i]+=temp;
			k++;
		}
		
		cout<<dot[i];
		if(i!=3)
			cout<<".";
	}
	cout<<endl;
	delete dot;
}
//************************************
void change(int *c,int (*&bin)[8])                        //十进制转变成32位二进制数并输出
{	
	for(int i=0;i<4;i++)
	{
		for(int j=7;j>=0;j--)
		{
			bin[i][j]=c[i]%2;
			c[i]=c[i]/2;
		}
	}
	

	cout<<endl;
}


void changetobinary(char *a,int (*&bin)[8])                     //点分十进制转变成二进制
{
	char (*b)[3];             //将点分十进制去掉.分成四段
	b=new char[4][3];

	int i=0,j=0,k=0;
	while(a[j]>0)
	{
		while(a[j]!='.'&&a[j]>0)//=
		{
			b[i][k]=a[j];
			j++;
			k++;
		}
		while(k<3)
		{
			b[i][k]=0;
			k++;
		}
		i++;
		k=0;
		j++;
	}

	int *c;                       //c存放四段的十进制值
	c=new int[4];

	for(i=0;i<4;i++)
		c[i]=0;

	for(i=0;i<4;i++)
	{
		int k=0;
		for(j=2;j>=0;j--)
		{
			if(j==2)
			{
				while(b[i][j]==0)
					j--;
			}
			
			
				int temp=0;
				temp=(int)b[i][j]-48;
				c[i]+=temp*pow(10,k);
				k++;
			
		}
	}//end for

	change(c,bin);

	delete b;
	delete c;
}

//********************************
void judge(int (*a)[8])               //输入一个32位二进制地址,判断该地址的类型(A~E),输出网络前缀和主机后缀(A~C)
{
	int i=0,j=0;
	
	if(a[0][0]==0)
	{
		printf("这是一个A类地址。\n网络前缀是:\n");
		for(j=1;j<8;j++)
				printf("%d",a[i][j]);
		printf("\n主机后缀是:\n");
		for(i=1;i<4;i++)
			for(j=0;j<7;j++)
				printf("%d",a[i][j]);

		printf("\n");
	}

	else if(a[0][1]==0)
	{	
		printf("这是一个B类地址。\n网络前缀是:\n");
		for(i=0;i<=1;i++)
		{
			if(i==0)
				for(j=2;j<8;j++)
					printf("%d",a[i][j]);
			else
				for(j=0;j<8;j++)
					printf("%d",a[i][j]);
		}
		printf("\n主机后缀是:\n");
		for(i=2;i<4;i++)
			for(j=0;j<8;j++)
				printf("%d",a[i][j]);
		printf("\n");
	}

	else if(a[0][2]==0)
	{	
		printf("这是一个C类地址。\n网络前缀是:\n");
		for(i=0;i<=2;i++)
		{
			if(i==0)
				for(j=3;j<8;j++)
						printf("%d",a[i][j]);
			else
				for(j=0;j<8;j++)
						printf("%d",a[i][j]);
		}
		printf("\n主机后缀是:\n");
		i=3;
		for(j=0;j<8;j++)
			printf("%d",a[i][j]);
		printf("\n");
	}

	else if(a[0][3]==0)
		printf("这是一个D类地址。(多播地址)\n");
	else if(a[0][4]==0)
		printf("这是一个E类地址。(保留给将来使用)");
}

//***************************CIDR******************************************
void and(int (*a)[8],int (*b)[8],int (*&c)[8])                 //两个二维数组的与运算,返回结果c
{
	for(int i=0;i<4;i++)
		for(int j=0;j<8;j++)
		{
			if(a[i][j]==0||b[i][j]==0)
				c[i][j]=0;
			else
				c[i][j]=1;
		}
}

//*************************************
int com(int (*a)[8],int (*b)[8])             //判断两个用二进制表示的地址是否一样,是返回1,否则返回0
{
	for(int i=0;i<4;i++)
		for(int j=0;j<8;j++)
			if(a[i][j]!=b[i][j])
				return 0;

	return 1;
}



//***********************************main function************************

void main()
{
	int (*a)[8];
	a=new int[4][8];
	char*str=new char[16];
	int (*bin)[8];               //32位二进制地址
	bin=new int[4][8];
	int i;
	int j;
	int k;
	//used for case 4
	char *add=new char[20];                    //add保存一个CIDR 斜线表示的网络地址
	char *length=new char[3];
	int (*yanma)[8];
	yanma=new int[4][8];               //子网掩码
	int len=0;                  //子网掩码长度
	int (*andresult)[8]=new int[4][8];      
	//case 6
	char (*des)[16];
	des=new char[4][16];
	int (*yanma0)[8]=new int[4][8];   
	int (*yanma1)[8]=new int[4][8];         
	int (*yanma2)[8]=new int[4][8];         
	int (*yanma3)[8]=new int[4][8];  
	int (*andresult2)[8]=new int[4][8];   
    int (*bin1)[8];               //暂存输入得到的地址的32位二进制地址
	bin1=new int[4][8];
//
	char flag;
	printf("**********************************************");
	printf("\n请选择 :\n");
	printf("1.二进制IP地址转变成点分十进制地址\n2.点分十进制地址转变成二进制IP地址\n3.输入一个32位二进制地址,判断该地址的类型(A~E),输出网络前缀和主机后缀(A~C)\n");
	printf("4.输入一个CIDR 斜线表示的网络地址,输出用点分十进制表示的网络前缀和可用的地址范围\n5.抽取报头中的所有字段,以十六进制的形式输出这些值(注意:该数据报文件保存在同目录下的IPpacket.txt文件中)\n");
	printf("6.在路由器B上,输入一系列目的IP地址,输出正确的下一跳\n");
	printf("\n请输入您的选择(1或2或3或4或5或6): ");
	flag=getchar();
	getchar();
	printf("\n");
	
	switch(flag)
	{
	case '1':

//***************二进制IP地址转变成点分十进制地址******************************
	//	{	
		printf("请输入32位二进制IP地址: (格式如:00001111000011110000111100001111,注意格式连续32位二进制数)\n ");
		char temp;
		for(i=0;i<4;i++)
			for(int j=0;j<8;j++)
			{	
				temp=getchar();
				a[i][j]=(int)temp-48;
			}
	

		printf("\n该32位二进制IP地址对应的点分十进制地址为 : ");
		changetodotdecimal(a);	
		break;	
	//	}
//***************点分十进制地址转变成二进制IP地址******************************
	case '2':
//		{
		printf("请输入点分十进制IP地址:(格式如:1.1.1.1) \n");
		gets(str);
		printf("\n您输入的IP地址为 : ");
		puts(str);
		cout<<endl;
		changetobinary(str,bin);
		cout<<"该IP地址对应的32位二进制地址为 :\n";
		for(i=0;i<4;i++)
		{
			for(int j=0;j<8;j++)
			{	
				if(j%4==0)
					cout<<" ";
				cout<<bin[i][j];
			}
		}
		printf("\n");
		cout<<endl;
		break;


	
//************************输入一个32位二进制地址,判断该地址的类型(A~E),输出网络前缀和主机后缀(A~C)***************
	case '3':
		printf("请输入32位二进制IP地址:(格式如:00001111000011110000111100001111,注意格式) \n ");
		char temp1;
		for(i=0;i<4;i++)
			for(int j=0;j<8;j++)
			{	
				temp1=getchar();
				a[i][j]=(int)temp1-48;
			}
		judge(a);
		break;
//**************输入一个CIDR 斜线表示的网络地址,输出用点分十进制表示的网络前缀和可用的地址范围*********
	case '4':
		
		i=0;
		printf("输入一个CIDR 斜线表示的网络地址(格式如:'255.254.1.24/23',注意格式 ):\n");
		gets(add);
		printf(" 您输入的CIDR 斜线表示的网络地址是 :  ");
		puts(add);
		//获取网络地址,去掉了/之后的
		while(add[i]!='/')
		{
			str[i]=add[i];
			i++;
		}
		for(j=i;j<16;j++)
			str[j]=0;
	//	printf("去掉了/之后的点分十进制地址为:");
	//	puts(str);
		changetobinary(str,bin);
		////获取网络长度
		i++;
		j=0;
		while(add[i]>0)
		{
			length[j]=add[i];
			i++;
			j++;
		}
		for(k=j;k<2;k++)
			length[k]=0;
		//把长度转变为int
		if(length[1]!=0)            //长为两位数
		{
			len=(int)length[1]-48;
			len+=((int)length[0]-48)*10;
		}
		else               //长为一位数
			len=(int)length[0]-48;

		//获取掩码
		int temp11,temp21;
		temp11=len/8;
		temp21=len%8;
		for(i=0;i<temp11;i++)
			for(j=0;j<8;j++)
				yanma[i][j]=1;
		for(j=0;j<temp21;j++)
			yanma[temp11][j]=1;
		
		for(j=temp21;j<8;j++)
			yanma[temp11][j]=0;
		for(i=temp11+1;i<4;i++)
			for(j=0;j<8;j++)
				yanma[i][j]=0;
		//将掩码与地址进行与运算
		and(yanma,bin,andresult);
		//将与运算结果转变成点分十进制
		printf("网络前缀:  ");
		changetodotdecimal(andresult);
	

		printf("可用的地址范围 :");
		changetodotdecimal(andresult);
		printf("  to   ");
		temp11=len/8;
		temp21=len%8;
		for(j=temp21;j<8;j++)
			andresult[temp11][j]=1;
		for(i=temp11+1;i<4;i++)
			for(j=0;j<8;j++)
				andresult[i][j]=1;
		changetodotdecimal(andresult);

		printf("\n");
		break;	
//*************************抽取报头中的所有字段,以十六进制或点分十进制的形式输出这些值***************
//********************该数据报保存在同目录下的IPpacket.txt文件中 *************************
	case '5':
		FILE *fp;
		fp=fopen("IPdatapacket.txt","r");
		char temp2;
		int headlength;
		temp2=fgetc(fp);
		printf("报头为: \n");
		putchar(temp2);
		if(temp2=='4')               //ipv4 数据报
		{
			temp2=fgetc(fp);               //temp*4个字节
			putchar(temp2);
			if(temp2>48&&temp2<58)            //1~9
				headlength=(int)temp2-48;
			else if(temp2<71&&temp2>64)         //ABCDEF
				headlength=(int)temp2-55;
			else if(temp2<103&&temp2>96)         //abcdef
				headlength=(int)temp2-87;
			else 
				printf("数据报出错!");
			int counter=2;
			while(counter<headlength*8)
			{
				while((temp2=fgetc(fp))==' ');
				counter++;
				putchar(temp2);
			}
		}
		else if(temp2=='6')
		{
			headlength=40;           //ipv6 报头固定为40字节
			int counter=1;             //记数字符个数
			while(counter<headlength*2)
			{
				while((temp2=fgetc(fp))==' ');
				counter++;
				putchar(temp2);
			}
		}
		else 
			printf("数据报头有错!");
		printf("\n");
		fclose(fp);
		break;
//*******************在路由器B上,输入一系列目的IP地址,输出正确的下一跳*************************
	case '6':
	


		//初始化目的地址
		strcpy(des[0],"30.0.0.0");     
		strcpy(des[1],"40.0.0.0");
		strcpy(des[2],"128.1.0.0");
		strcpy(des[3],"192.4.10.0");
		//
		for(j=0;j<8;j++)
			yanma0[0][j]=1;
		for(i=1;i<4;i++)
			for(j=0;j<8;j++)
				yanma0[i][j]=0;

		for(j=0;j<8;j++)
			yanma1[0][j]=1;
		for(i=1;i<4;i++)
			for(j=0;j<8;j++)
				yanma1[i][j]=0;
		
		for(i=0;i<2;i++)
			for(j=0;j<8;j++)
				yanma2[i][j]=1;
		for(i=2;i<4;i++)
			for(j=0;j<8;j++)
				yanma2[i][j]=0;

		for(i=0;i<3;i++)
			for(j=0;j<8;j++)
				yanma3[i][j]=1;
		for(j=0;j<8;j++)
				yanma3[3][j]=0;

		printf("输入一个目的IP地址:  ");
		gets(str);
		printf("您输入的目的IP地址是:  ");
		puts(str);
		
		changetobinary(str,bin);
		
		//
		and(yanma3,bin,andresult2);
		changetobinary(des[3],bin1);

		if(com(bin1,andresult2))
			printf("下一跳是: 128.1.0.9  \n ");
		//
		and(yanma2,bin,andresult);
		changetobinary(des[2],bin1);

		if(com(bin1,andresult2))
			printf("直接传送  \n ");
		//
		and(yanma1,bin,andresult2);
		changetobinary(des[1],bin1);

		if(com(bin1,andresult2))
			printf("直接传送  \n ");

		//
		and(yanma0,bin,andresult2);
		changetobinary(des[0],bin1);

		if(com(bin1,andresult2))
			printf("下一跳是:40.0.0.7 \n");

		break;
		default:break;
	}


		delete []a;
		delete str;
		//delete add;
		delete []bin;
}
		


		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -