📄 framer.cpp
字号:
/*! \file framer.cpp :
\brief 定义控制台应用程序的入口点。
*/
#include "stdafx.h"
#include "framer.h"
using namespace std;
/*! \fn bool frameheader(char* outfile,char* tempfile)
\brief 形成帧的前导码、帧定界符、目的地址和源地址,输出到输出文件。
\param char* outfile 为输出文件名
\param char* tempfile 临时文件名
\returns 输出成功,则返回为真
*/
bool frameheader(char* outfile,char* tempfile)
{
//数组存放7字节前导码、1字节帧定界符、6字节目的地址和6字节源地址。
unsigned char head[8]={0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAB};// 7字节前导码,每字节均为10101010,帧前导码10101011;
unsigned char add[12]={0x00,0x00,0xE4,0x86,0x3A,0xDC, //目标地址00-00-E4-86-3A-DC;
0x00,0x00,0x80,0x1A,0xE6,0x65}; //源地址00-00-80-1A-E6-65
ofstream tfile( tempfile );
ofstream ofile( outfile );
tfile.write( (char *) &head, sizeof head );
tfile.write( (char *) &add, sizeof add);
ofile.write( (char *) &head, sizeof head );
tfile.close();
ofile.close();
return true;
}
/*! \fn bool length(char* infile,char* tempfile)
\brief 将输入文件的字节长度文件数据输出到临时文件,不足46字节的以0补齐。
\param char* infile 输入文件名
\param char* tempfile 临时文件名
\returns 输出成功,则返回为真
*/
bool length(char* infile,char* tempfile)
{
ifstream ifile(infile,ios::binary);
ofstream tfile( tempfile,ios_base::binary|ios::app );
if(!ifile) //输入文件无法打开,返回失败。
{
cout<<"cannot open"<<infile<<endl;
return false;
}
char tempchar;
unsigned short c1,c2,bytecnt ;
ifile.seekg( 0, ios_base::end ); //找到二进制文件尾
c1=c2=bytecnt= ifile.tellg(); //数据字段长度计数器。
unsigned char b1=c1&0x00ff; //将数据长度字段输出到临时文件
c2>>=8;
unsigned char b2=c2;
tfile.put(b2);
tfile.put(b1);
ifile.seekg(0); //开始读取数据,并输出到临时文件
int cnt=bytecnt;
ifile.get(tempchar);
while(cnt>0)
{
cnt--;
tfile.put(tempchar);
ifile.get(tempchar);
}
if(bytecnt>46) //数据字段大于46字节,成功返回
{
tfile.close();
ifile.close();
return true;
}
tempchar=0;
for(int i=bytecnt;i<46;i++) //数据字段不足46字节,先用0补足46字节再返回;
tfile.put(tempchar);
tfile.close();
ifile.close();
return true;
}
/*! \fn bool crc(char* tempfile,char* outfile)
\brief 根据临时文件计算crc校验码,并把计算结果和临时文件的数据输出到输出文件。
\param char* tempfile 临时文件名
\param char* outfile 输出文件名
\returns 输出成功,则返回真。
*/
bool crc(char* tempfile,char* outfile)
{
unsigned char crc = 0x00; //crc校验码值(寄存器),初始化为0。
unsigned char gx = 0x07; //对应于G(x)=x8+x2+x1+x0
unsigned char oput = 0; //每次左移时,移出的一位
unsigned char temp;
unsigned char otemp;
ifstream tfile(tempfile,ios::binary);
if(!tfile) //临时文件无法打开,返回失败
{
cout<<"cannot open file";
return false;
}
tfile.seekg(0,ios_base::end); //寻找临时文件尾
int cnt=tfile.tellg(); //获得临时文件长
cnt=cnt-7; //7字节前导码、1字节帧定界符不用于计算crc但还要加上crc位本身
int cnt2=cnt;
tfile.seekg(8); //从第9位开始读取
ofstream ofile( outfile,ios::app|ios_base::binary );
tfile.read((char*)&otemp,sizeof (unsigned char));
while(cnt>0) //每次从临时文件中读取一字节,计算,然后写到输出文件
{
cnt=cnt-1;
if(cnt!=0) //非crc位
{
temp=otemp;
ofile.put(otemp);
}
else
temp=0; //cnt=0即为crc位,crc位为0
int i=0;
while(i<8) //对每一位入寄存器计算
{
oput = crc & 0x80; //取上次计算crc的最高位,此次左移即为输出位;
crc <<= 1; //寄存器左移一位
if (temp & 0x80) //每次取字节的最高位,作为输入,判断是否为0
{
crc |= 0x01; //非0,则将crc最低位与1取或,即最低为取一,其它位不变,即将1移入
//寄存器,若为0,则无需变化
}
temp <<= 1;
if ( oput ) //若输出位为1,则将crc与gx对应位取异或,
//若为0,取异或结果不变,无需计算
{
crc ^= gx;
}
i=i+1;
}
tfile.read((char*)&otemp,sizeof (unsigned char));
}
ofile.put(crc); //输出校验和数据
ofile.close();
tfile.close();
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(argc!=3) //输入命令行参数不合要求,返回失败
{
cout<<"USAGE:framer inputfile outputfile"<<endl;
cout<<"inputfile name:input1 || input2"<<endl;
return 1;
}
_TCHAR tname[20]; //生成临时文件的名字 t+输出文件名
tname[0]='t';
for(int j=0;argv[2][j]!='\0';j++)
tname[j+1]=argv[2][j];
tname[j+1]='\0';
if(frameheader(argv[2],tname)) //生成帧头部的前导码、帧定界符、目的地址和源地址,输出到输出文件
cout<<"frame header formed"<<endl;
else //失败则返回
{
cout<<"frame header form failed"<<endl;
return 1;
}
if(length(argv[1],tname)) //将输入文件的字节长度、文件数据输出到临时文件,不足46字节的以0补齐。
cout<<"data length count finished"<<endl;
else
{
cout<<"data length count failed"<<endl;
return 1;
}
if(crc(tname,argv[2])) //根据临时文件计算crc校验码,并把计算结果和临时文件的数据输出到输出文件。
cout<<"crc finished"<<endl;
else
{
cout<<"crc failed"<<endl;
return 1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -