计算机网络课设判断一个IP地址是否合法.docx
《计算机网络课设判断一个IP地址是否合法.docx》由会员分享,可在线阅读,更多相关《计算机网络课设判断一个IP地址是否合法.docx(14页珍藏版)》请在冰豆网上搜索。
计算机网络课设判断一个IP地址是否合法
1
课程设计目的
本设计要求编写程序,判断一个IP地址是否合法,并判断该地址是否属于一个给定子网。
从而考察读者是否对IP地址概念及其子网划分有非常清楚的认识。
2课程设计的要求
根据介绍的IP地址与子网划分的知识,编写程序判断IP地址的合法性及所属子网。
(1)以命令行形式运行
IPAddresssubnet_address/maskip_address
其中,IPAddress为程序名,subnet_address为子网地址,mask为掩码,ip_address为IP地址。
(2)输入容:
IP地址、子网地址与掩码是否合法,以及IP地址是否属于子网。
3相关知识
1.IP地址相关概念
所谓IP地址就是给每个连接在Internet上的主机分配的一个32bit地址。
按照TCP/IP(TransportControlProtocol/InternetProtocol,传输控制协议/Internet协议)协议规定,IP地址用二进制来表示,每个IP地址长
32bit,比特换算成字节,就是4个字节。
例如一个采用二进制形式的IP地址是“0001”,这么长的地址,人们处理起来也太费劲了。
为了方便人们的使用,IP地址经常被写成十进制的形式,中间使用符号“.”分开不同的字节。
于是,上面的IP地址可以表示为“10.0.0.1”。
IP地址的这种表示法叫做“点分十进制表示法”,这显然比1和0容易记忆得多。
大型的互连网络中应该有一个全局的地址系统,它能够给连接到互联网的每一台主机或者路由器分配一个唯一的全局地址。
TCP/IP协议的网络层使用的地址标识符叫做IP地址,IPv4中IP地址是一个32位的二进制地址。
网络中的每一台主机或者路由器至少有一个IP地址,在Internet中不允许有两个设备具有相同的IP地址。
如果一台主机或者路由器连接到两个或多个物理网络,那么它可以拥有两个或多个IP地址。
IP地址采用分层结构,由网络号与主机号两部分组成(如下图1所示):
网络号
主机号
图1
IP地址长度为32位,用点分十进制表示,格式为ⅹ.ⅹ.ⅹ.ⅹ,每个ⅹ为8位,每个ⅹ的值为0—255(例如202.113.29.119)。
根据不同的取值围,IP地址可以分为五类,IP地址中的前5位用于标识IP地址的类别,具体的分类规则如下:
·A类地址的第一位为0。
·B类地址的前两位为10.
·C类地址的前三位为110。
·D类地址的前四位为1110。
·E类地址的前五位为11110。
五类IP地址的结构如下图2所示;
0
网络号(7位)
主机号(24位)
10
网络号(14位)
主机号(16位)
110
网络号(21位)
主机号(8位)
1110
组播地址(28位)
11110
保留用于课程设计和将来使用
图2
A类IP地址结构适合用于有大量主机的大型网络。
由于主机号长度为24位,因此每个A类网络的主机IP数理论上为224=16777216。
B类IP地址适合用于一些国际性大公司与政府机构等中等大小的组织。
由于网络IP长度为14位,因此允许有214=16384个不同的B类网络,实际允许连接16382个网络。
C类IP地址适合用于一些小公司与普通的研究机构。
2.子网的划分
划分子网实际上就是在IP地址系统中增加一个层次。
三级IP地址的表示方法为netID-subnetID-hostID。
第一级网络号定义了网点的位置;第二级子网号定义了物理子网;第三级主机号定义了主机和路由器到物理网络的连接。
三级层次的IP地址,一个IP分组的路由器的过程分为三步:
第一步将分组转发给网点,第二步转发给物理子网,第三步转发给确切的主机。
当三级层次的IP地址提出后,一个很显示的问题是:
如何从一个IP地址提取出子网号。
因此,提出了子网掩码(subnetmask)的概念。
子网掩码有时也叫做子网掩码。
子网掩码表示方法:
网络号与子网号置1,主机号置0。
4.课程设计分析
4.1程序大致设计过程:
1.分别判断子网号、掩码和IP地址的基本格式是否合法。
2.如果三者的基本格式都合法,才调用判定“IP地址是否为子网成员”的函数。
该函数同时判别子网号与掩码是否匹配,子网号为全0或全1,主机号为全0、全1.
4.2实验流程图如下:
1.主流程图
图3 主流程图
2.验证ip地址合法性流程图
图4 验证ip地址合法性流程图
3验证子网掩码合法性流程图
图5验证子网掩码合法性流程图
5程序代码
#include
#include
#include
#include
//定义ip地址类
classipTest
{
charip[15];
charsubnetPlusMask[18];
charsubnet[10];
charTempIp[15];
charTempSub[10];
intmask;
boolmaskIsValid;
public:
ipTest(char*,char*);
~ipTest(){};
boolNoIllegalChar(char*);
boolipIsValid(char*);
boolsubnetIsValid(char*);
voidbelong();
voidprint();
};
voidmain(intargc,char*argv[])
{
//检查输入命令格式
if(argc!
=3)
{
cout<<"PleaseInputmand:
ip_testsubnet/maskip";
return;
}
else
{
//判断IP地址长度是否超出
if(strlen(argv[1])>18)
{
cout<<"Subnet/maskistoolong!
";
return;
}
if(strlen(argv[2])>15)
{
cout<<"IpAddressistoolong!
";
return;
}
//实例化ipTest类
ipTesttest(argv[1],argv[2]);
test.print();
}
}
//IP地址类构造函数
ipTest:
:
ipTest(char*subnetPlusMask,char*ip)
{
maskIsValid=true;
chartemp[2];
//将'1'前的字符复制到subnet中
intsmLen=strlen(subnetPlusMask);
for(inti=0;i='/';i++)
{
this->subnet[i]=subnetPlusMask[i];
this->TempSub[i]=subnetPlusMask[i];
}
subnet[i]='\0';
TempSub[i]='\0';;
//初始化
if(i<=smLen-2)
{
if(i>=smLen-2)
{
temp[0]=subnetPlusMask[i+1];
if(!
isdigit(temp[0]))
maskIsValid=false;
}
else
{
if(i==smLen-3)
{
temp[0]=subnetPlusMask[i+1];
temp[1]=subnetPlusMask[i+2];
if(!
(isdigit(temp[0])&&isdigit(temp[1])))
maskIsValid=false;
}
}
mask=atoi(temp);
if(mask<0||mask>32)
maskIsValid=false;
}
else
maskIsValid=false;
//为subnetPlusMask与ip赋值
strcpy(this->subnetPlusMask,subnetPlusMask);
strcpy(this->ip,ip);
strcpy(this->TempIp,ip);
}
//调用判别函数并输出结果
voidipTest:
:
print()
{
boolsubIsV=subnetIsValid(TempSub);
boolipIsV=ipIsValid(TempIp);
//判断子网是否合法
if(!
subIsV)
cout<<"Subnetisinvalid"<else
cout<<"Validsubnet:
"<//判断掩码是否合法
if(!
maskIsValid)
cout<<"Maskisinvalid"<else
cout<<"Validmask:
"<//判断是否IP地址合法
if(ipIsV)
cout<<"IPadressisinvalid"<else
cout<<"Validipaddress:
"<//判断IP地址是否属于子网
if(subIsV&&ipIsV&&maskIsValid)
belong();
}
//判断是否含有非数字字符
boolipTest:
:
NoIllegalChar(char*ch)
{
unsignedinti;
unsignedintk=0;
//判断每位是否为数字字符
for(i=0;iif(isdigit(*(ch+i))==0)
returnfalse;
returntrue;
}
//判断IP地址是否合法
boolipTest:
:
ipIsValid(char*ip)
{
charch[]=".";
char*token,*dot[4];
intiplen=0;
//以"."标志将字符串按节分开
//以"."标志将IP字符串按节分开
token=strtok(ip,ch);
while(token!
=NULL)
{
dot[iplen]=token;
iplen++;
token=strtok(NULL,ch);
}
//判断IP地址的段数
if(iplen!
=4)
returnfalse;
//有非法字符或某段值非法
for(inti=0;i<4;i++)
if(!
NoIllegalChar(dot[i])||atoi(dot[i])>255)
returnfalse;
returnfalse;
}
//判断子网是否合法
boolipTest:
:
subnetIsValid(char*subnet)
{
//调用判别地址合法性函数
if(!
ipIsValid(subnet))
returnfalse;
returntrue;
}
//判断IP地址是否为子网成员
voidipTest:
:
belong()
{
intsubLen=strlen(subnet);
intipLen=strlen(ip);
unsignedintiIPA,iSubA,iMask;
unsignedcharsubA[4],ipA[4];
chartemp[3];
inti,j,t=0;
for(i=0,j=0;i{
//temp数组中放'.'间的串
if(subnet[i]!
='.')
temp[j++]=subnet[i];
else
{
subA[3-t]=atoi(temp);
j=0;
t++;
temp[0]=temp[1]=temp[2]='\0';
}
}
subA[0]=atoi(temp);
temp[0]=temp[1]=temp[2]='\0';
iSubA=*(unsignedint*)subA;
for(i=0,j=0;i{
if(ip[i]!
='.')
temp[j++]=ip[i];
else
{
ipA[3-t]=atoi(temp);
j=0;
t++;
temp[0]=temp[1]=temp[2]='\0';
}
}
ipA[0]=atoi(temp);
iIPA=*(unsignedint*)ipA;
//获得掩码子网号与掩码不匹配
iMask=0xffffffff;
iMask<<=(32-mask);
//子网号与掩码不匹配
if((iSubA|iMask)!
=iMask)
{
cout<<"Subnetandmasknotmatch!
";
return;
}
//子网号为全1
if((iSubA^iMask)==0)
{
cout<<"Subnetisall1!
";
return;
}
//子网号为全0
if((iSubA&iMask)==0)
{
cout<<"Subnetisall0!
";
return;
}
//IP地址与子网号比较
if((iSubA)==(iIPA&iMask))
{
//IP地址全为1
if((iSubA|iMask)==0xffffffff)
{
cout<<"Ipaddressisall1!
";
return;
}
//IP地址全为0
if((iSubA|iMask)==iMask)
{
cout<<"Ipaddressisall0!
";
return;
}
//IP地址属于子网
cout<return;
}
else
cout<}
6.运行结果与分析
分析:
本题需要在另外下载一个IP地址捕捉器,在有网的情况下才能获得IP地址,程序才能进行。
程序流程分析:
先分别判断子网号、掩码和IP地址的基本格式是否合法。
如果三者的基本格式都合法,才调用判定“IP地址是否为子网成员”的函数。
该函数同时判别子网号与掩码是否匹配,子网号为全0或全1,主机号为全0、全1。
7.参考文献
[1]希仁编著.计算机网络(第5版).:
电子工业,2008
[2]吴宜功吴英编著.计算机网络课程设计(第2版). :
机械工业,2012