3,设置路由表
方法名称: CentralRout::SetRoutTable
方法参数: 无
返回值: 无
方法的目的: 填写路由表。局部变量int **result,由路由计算方法填充,是目标路由器标号与应传输的下一个路由器标号的对映表,核心过程就是通过该变量完成路由表的设置。
可能的出错: 文件操作失败:系统退出
// 设置路由表
void CentralRout::SetRoutTable(void)
{
int **result = NULL;
int routNum = routTable.GetRoutNum();
TableNode _routTable[MAX_ROUT_TABLE_SIZE];
int selfID = 0;
int *index = NULL;
unsigned int **addr = NULL;
std::fstream indexFile;
char *indexFileName="IndexAddr.txt";
//申请空间
result = new int *[routNum];
for(int i=0;i<routNum;i++)
result[i]=new int[2];
index = new int[routNum];
addr = new unsigned int *[routNum];
for(int i=0;i<routNum;i++)
addr[i] = new unsigned int[IP_ADDRESS_LENGTH];
//打开存储“路由号与地址对应表”文件
indexFile.open(indexFileName,std::ios_base::in|std::ios_base::out);
if(indexFile.fail())
{
std::cout<<"\n\n文件("<<indexFileName<<") 打开失败.\n\n";
char ch;
std::cin>>ch;
exit(-1);
}
for(int i=0;i<routNum;i++)
{
indexFile>>index[i];
for(int j=0;j<IP_ADDRESS_LENGTH;j++)
indexFile>>addr[i][j];
}
//获得本路由号
for(int i=0;i<routNum;i++)
if(AddrEqual(selfAddress,addr[i]))
{
selfID = i;
break;
}
//路由算法执行
if(RoutCompute!=NULL)
(*RoutCompute)(netArray,valArray,result,routNum,selfID);
else{
std::cout<<"\n\n路由计算尚未设置,系统退出...\n\n";
exit(-1);
}
//计算本路由器之路由表
for(int i=0;i<routNum;i++)
{
for(int j=0;j<routNum;j++)
if(result[i][0]==index[j])
_routTable[i].SetAddressTo(addr[j]);
for(int j=0;j<routNum;j++)
if(result[i][1]==index[j])
_routTable[i].SetAddressNextHop(addr[j]);
}
routTable.SetTable(_routTable);
indexFile.close();
/*注释部分为打印路由表
std::cout<<"\n-------------------------------------------------";
for(int i=0;i<routNum;i++)
{
std::cout<<"\n";
for(int j=0;j<IP_ADDRESS_LENGTH;j++)
std::cout<<_routTable[i].addressTo[j];
std::cout<<"->";
for(int j=0;j<IP_ADDRESS_LENGTH;j++)
std::cout<<_routTable[i].addressNextHop[j];
std::cout<<"\n";
}
std::cout<<"---------------------------------------------------\n";
*/
delete []result;
delete []index;
delete []addr;
}
四,网络数据的传输
这是另一个比较关键的部分。本部分的实现,大部分为网络传输原语的模拟。这里要尤其注意语义的完备性,考虑网络传输中的分布环境的各种因素。当然,本方案的实现仍一切就简。若对网络环境进行实时模拟,可以进行代码扩充。
1,网络向路由器端口发送数据
方法名称: CentralRout::NetWriteData
方法参数: NetData & _netData
返回值: bool类型,true为写成功,否则则是网络已经涌塞。
方法的目的: 网络中向路由器端口写数据的过程。对IPData和Message分别处理。如果成功则调用路由器读端口数据的过程。
可能的出错: 无
// 网络向路由器端口发送数据
bool CentralRout::NetWriteData(NetData & _netData)
{
//向控制台显示位置
std::cout<<"\nAt Rout:\t";
for(int i=0;i<IP_ADDRESS_LENGTH;i++)
std::cout<<selfAddress[i];
std::cout<<std::endl;
//写入的是IP数据包
if(!_netData.IsMessage() && AddrEqual(_netData.GetNextHop(),selfAddress) )
{//id是路由器内跟踪数据包与应答消息的对应关系的关键变量
id = id + 0.000001;
NetData message(true);
message.ID = _netData.ID;
_netData.ID = id;
//返回接收成功的消息
message.SetAddressFrom(selfAddress);
message.SetAddressTo(_netData.GetPreHop());
message.SetPreHop(selfAddress);
message.SetNextHop(_netData.GetPreHop());
//数据包已到达目的路由器
if(AddrEqual(_netData.GetAddressTo(),selfAddress))
std::cout<<"\n\nOK! Success for one IPData!\n\n";
else{//数据包未到达目的路由器,继续处理
dataListLength++;
if(dataListLength>=MAX_DATA_QUEUE_LENGTH)
{//网络涌塞发生
std::cout<<"\n端口数据包过多,网络发生涌塞,写数据包失败...\n";
return false;
}//end of if
//写数据包
dataInList.push_back(_netData);
std::cout<<"\n\t接收IPData成功...\n";
//路由器读取数据包
ReceiveData();
}//end of else
//送应答消息
dataOutList.push_front(message);
} else //写入的是网络消息
if(_netData.IsMessage() && AddrEqual(_netData.GetNextHop(),selfAddress))
{//接收应答消息后,则是删除已发送成功的数据包
std::cout<<"\n\t接收Message成功...\n";
for( dataIter = dataOutList.begin();
dataIter!=dataOutList.end(); dataIter ++)
{
//删除已发送成功的IP数据包
if(_netData.ID == dataIter->ID )
{
dataOutList.erase(dataIter);
dataIter = dataOutList.begin();
}
}//end of for
}//end of else if
return true;
}
<未完>