/***************************************************************
*该程序的功能是解析MAC帧与封装MAC帧,并对封装的帧进行模拟发送。
*程序的执行以“-u”代表解析帧,以“-e”代表封装并模拟发送帧。
*使用时需按照一定的格式输入.解析的帧需要是连续的
****************************************************************/
#include <fstream.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <iomanip.h>
#include <iostream.h>
#include <windows.h>
#define random(x) (rand()%x)
/*********************************************************
*计算2的K次方函数,输入K的值,返回2的K次方的值
**********************************************************/
int square(int k)
{
int c=1;
for(int i=0;i<k;i++)
{
c*=2;
}
return c;
}
/********************************************************
*计算CRC校验值函数,参考书中所带光盘中程序
*********************************************************/
void CheckCRC(int &chCurrByte,int chNextByte)
{
for (int nMask = 0x80; nMask > 0; nMask >>= 1)
{
if ((chCurrByte & 0x80) != 0) // 首位为1:移位,并进行异或运算
{
chCurrByte <<= 1; // 移一位
if ( (chNextByte & nMask) != 0) // 补一位
{
chCurrByte |= 1;
}
chCurrByte ^= 7; // 首位已经移出,仅对低8位进行异或运算,7的二进制为0000,0111
}
else // 首位为0,只移位,不进行异或运算
{
chCurrByte <<= 1; // 移一位
if ( (chNextByte & nMask) != 0) // 补一位
{
chCurrByte |= 1;
}
}
}
}
/********************************************************************************
*在文件中查找合法的帧。如果含有合法的帧,则返回1,没有则返回0。输入为打开的文件和文件的长度。
*在文件中查找前导符和帧前定位符,如果没有超出文件的长度,并且含有符合帧头长度的
*空间,则判定为有合法的帧
**********************************************************************************/
bool FindFrame(fstream file,int nFileEnd)
{
while(true)
{
for(int j=0;j<7;j++)
{
if(file.tellg()>=nFileEnd)
{
return 0;
break;
}
if(file.get()!=0xaa)
{
j=-1;
}
} //找到连续的7个0xaa,即前导符
if(file.tellg()>=nFileEnd)
{
return 0;
break;
} //安全性检测
if(file.tellg()+14>nFileEnd)
{
return 0;
break;
} //检查是否含有足够的帧头空间
if(file.get()==0xab)
{
return 1;
break;
} //检查前导符
}
}
/***********************************************************************
*打印帧的信息函数。找到合法的帧后,调用此函数可打印出帧的内容。
*并且可以通过校验CRC,判断帧中CRC是否正确,判断帧是否是可接受的帧
***********************************************************************/
void PrintFrame(fstream file,int nFileEnd,int Count)
{
int nFileMid2,nFileMid3;//创建变量,记录指针位置和文件长度
int nCheck,nDataLength;//创建变量,记录CRC校验结果,数据字段长度
bool bAccept;
char ch;
int c;//程序中用到的临时变量
nFileMid2=0;
nFileMid3=0;
nCheck=0;//初始化变量值
cout<<"====================第"<<Count<<"个帧==================="<<endl;
cout<<endl<<"序号:\t"<<Count;
file.seekg(-8,ios::cur);
cout<<endl<<"前导符:\t";
cout.setf(ios::uppercase);
for(int i=0;i<7;i++)
{
cout<<hex<<file.get()<<dec<<" ";
}
cout<<endl<<"帧前定位符:\t"<<hex<<file.get();//打印序号,前导符和帧前定位符
cout<<endl<<"目的地址:\t";
for(i=0;i<6;i++)
{
c=file.get();
cout.width(2);
cout<<hex<<c<<dec<<(i==5?" ":"-");//打印目的地址
if(i==0)
{
nCheck=c;
}
else
{
CheckCRC(nCheck,c);
} //校验目的地址段,从此处开始CRC校验
}
cout<<endl<<"源地址: \t";
for(i=0;i<6;i++)
{
c=file.get();
cout.width(2);
cout<<hex<<c<<dec<<(i==5?" ":"-");//打印源地址
CheckCRC(nCheck,c);
}
cout<<endl<<"长度字段:\t";
c=file.get();
cout.width(2);
cout<<hex<<c<<dec<<" ";
CheckCRC(nCheck,c);
c=file.get();
cout.width(2);
cout<<hex<<c<<dec<<" ";//打印长度字段
CheckCRC(nCheck,c);
nFileMid2=file.tellg();//记录数据字段的开始
cout<<endl<<"数据字段:\t";
if(FindFrame(file,nFileEnd))//查找数据字段的结尾。因为文件中的帧均为连续存储,则通过查找下帧的位置来获得。
{
nFileMid3=file.tellg();
file.seekg(nFileMid2,ios::beg);
nDataLength=nFileMid3-nFileMid2-9;
for(i=0;i<nDataLength;i++)
{
ch=file.get();
cout<<ch;
CheckCRC(nCheck,(int)ch);
}//如果找到下一帧,则根据帧结构和记录的数据字段开始位置,计算出数据字段的长度并打印和校验
}
else
{
nFileMid3=file.tellg();
file.seekg(nFileMid2,ios::beg);
nDataLength=nFileMid3-nFileMid2-1;
for(i=0;i<nDataLength;i++)
{
char ch;
ch=file.get();
cout<<ch;
CheckCRC(nCheck,(int)ch);
}//如果已是最后一帧,则同样获得数据字段的长度,并打印和校验
}
cout<<endl<<"CRC校验:";//开始核对CRC校验
c=file.get();
int temp=nCheck;
CheckCRC(nCheck,c);
if((nCheck & 0xff)==0)
{
cout.width(2);
cout<<"正确:"<<hex<<c;
bAccept=true;//CRC值正确
}
else
{
cout<<"错误 ";
CheckCRC(temp,0);
cout<<c<<"(应为):"<<hex<<(temp & 0xff);
bAccept=false;//CRC值错误,打印正确的CRC值
}
if(nDataLength<46 || nDataLength>1500)//如果数据字段长度不符合规则,将帧的状态设置为不可接受
{
bAccept=false;
}
cout<<endl<<"状态:\t\t" << (bAccept ? "Accept" : "Discard") << endl <<endl;
}
/***********************************************************
*找到文件长度的函数。
************************************************************/
int FindTheEnd(fstream file)
{
int n;
file.seekg(0,ios::end);
n=file.tellg();
file.seekg(0,ios::beg);
return n;
}
/**********************************************************************
*模拟发送函数。用随机数表示总线和冲突的状态。每一次调用产生不同的
*随机数,模拟实际情况中发送的情况。其中延迟算法采用的是作业中提供的算法
***********************************************************************/
void SimuSend()
{
srand((int)time(0));
int Count1=0,tem,t;
double time;
while(true)
{
while(random(100)<50) //取随机数范围0~100,当结果小于50时代表总线忙
{
cout<<endl<<"总线忙";
}
cout<<endl<<"总线空闲"<<endl<<"启动发送";
if(random(100)<50) //取随机数范围0~100,当结果小于50时代表有冲突
{
cout<<endl<<"有冲突"<<endl<<"冲突加强"<<endl<<"冲突次数加1";
Count1++;
if(Count1>16)
{
cout<<"发送失败";
break;
}
else
{
cout<<endl<<"计算后退延迟时间"<<endl<<"后退时间为";
t=(Count1>10)?Count1:10;
tem=square(t);
time=tem*0.005*random(100)/50;//按照退避时间算法计算退避时间
cout<<time<<"s"<<endl<<"等待后退时延结束";
Sleep(unsigned long(time*1000));
}
}
else
{
cout<<endl<<"无冲突"<<endl<<"发送成功";
break;
}
}
}
/********************************************************************
*封装包的应用中,将数据写入封包的函数。
*********************************************************************/
void WriteIn(fstream file,char* c,int Length)
{
int Begin;
Begin=file.tellg()+8;
for(int i=0;i<7;i++)
{
file.put((char)0xaa);
}
file.put((char)0xab);
char DestAddr[6]={char (0xff),char (0xff),char (0xff),char (0xff),char (0xff),char (0xff)};
file.write(DestAddr,6);
char SourAddr[6]={char (0x00),char (0x16),char (0x76),char (0xb4),char (0xe4),char (0x77)};
file.write(SourAddr,6);//写入规定的目的地址和源地址
int j,k;
c[Length]='\0';
j=Length;
file.put(char(j>>8));
file.put(char(j&0xff));
j=0;
while(c[j]!='\0')//将数据字段写入帧中
{
file.put(c[j]);
j++;
}
if(j<46)//如果写入数据长度小于46,则填充0
{
for(k=j;k<46;k++)
file.put(char(0x00));
}
file.
没有合适的资源?快使用搜索试试~ 我知道了~
Frame-analysis.tar.gz_Mac帧
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 184 浏览量
2022-09-22
22:48:45
上传
评论
收藏 11KB GZ 举报
温馨提示
共7个文件
cpp:2个
dsw:1个
plg:1个
解析和封装MAC帧,对于过长的帧也可以实现解析,完全遵循Ethernet帧的格式的要求.
资源详情
资源评论
资源推荐
收起资源包目录
Frame-analysis.tar.gz (7个子文件)
源码
exec1.opt 53KB
2.cpp 39B
exec1.dsp 4KB
1.cpp 10KB
exec1.ncb 49KB
exec1.dsw 535B
exec1.plg 878B
共 7 条
- 1
JonSco
- 粉丝: 66
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0