📄 exp3.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 + -