计算机网络-帧封装C
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*将fileinput文件中的数据封装成帧,封装好的帧写入到文件中.
如果数据长度小于46字节,则补全到46字节,如果数据长度大于1500,则封装成多个帧*/ #include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1500
/*帧封装函数,完成把给定的文件封装成帧的功能*/
int zhenfengzhuang(char *fileinput)
{
int i,lastDataPacket,pyl; //记录最后一个帧,记录偏移量
FILE *fileIn,*fileOut;
long startjyw,endjwy; //开始检验位置,结束检验位置
short dataNum; //记录校验字节个数
if((fileIn = fopen(fileinput,"r+")) == NULL)
{
printf("%s","打开文件失败");
return 1;
}
if((fileOut = fopen("E:\\out.txt","w+")) == NULL)
{
printf("%s","写入文件失败");
return 1;
}
printf("\n封装后的文件保存地址:E:\\out.txt");
/**先把fpIn指针退回到文件结尾处。
再得到文件位置指针
当前位置相对于文件首的偏移字节数,即可得到内容的长度*/ fseek(fileIn,0,SEEK_END);
pyl = ftell(fileIn);
//计算整1500数据包个数
int dataPacketNum = pyl/1500;
//把文件指针重新回到文件开头。
rewind(fileIn);
/*for循环处理大于1500B的情况,当大于1500时
自动转换到下一个数据帧中*/
for(int j = 0;j <= dataPacketNum; j++)
{
char data[MAXSIZE]; //数据临时存储数组
//写入帧前导码,十六进制0xaa
printf("\n帧的前导码:");
for(i = 0;i < 7; i++)
{
fputc(0xaa,fileOut);
printf("%X ",0xaa);
//写入帧定界符
fputc(0xab,fileOut);
printf("%X ",0xab);
unsigned char mudiMac[6] = {0x4a,0x7b,0x3c,0x5d,0xe6,0x8f};//模拟目的MAC 地址
unsigned char yuanMac[6] = {0x34,0xe6,0xf7,0xb4,0xa6,0x52};//模拟源MAC地址
//记录开始进行校验的位置,因为校验是从前导码以后开始的
startjyw = ftell(fileOut);
printf("\n帧的目的MAC地址:");
for(i = 0; i < 6; i++)
{
fputc(mudiMac[i],fileOut);//写入目的MAC
printf("%X ",mudiMac[i]);
}
printf("\n帧的源MAC地址:");
for(i = 0; i < 6; i++)
{
fputc(yuanMac[i],fileOut); //写入源MAC
printf("%X ",yuanMac[i]);
//不是最后一个数据,则前面的数据都应该是1500,所以按最大数据数算
if(j != dataPacketNum)
{
//添加长度字段
fputc(char(1500/256),fileOut);
fputc(char(1500%256),fileOut);
fread(data,sizeof(char),1500,fileIn);
fwrite(data,sizeof(char),1500,fileOut);
//记录开插入校验码的位置
endjwy = ftell(fileOut);
fputc(0x00,fileOut); //添加辅助检验字段
dataNum = short(ftell(fileOut)) - (short)startjyw; //计算检验的字段长度}
else
{
//得到最后一个数据块的位置
lastDataPacket = ftell(fileIn);
//剩下有多少字节
int hasLongs = pyl - dataPacketNum * 1500;
//还有多少不够46B
int surplusLongs = 46 - hasLongs;
//记录长度字段
fputc(char(hasLongs/256),fileOut);
fputc(char(hasLongs%256),fileOut);
//先读取剩余的所有数据
fread(data,sizeof(char),pyl - lastDataPacket,fileIn);
//如果不足,则填充
if(surplusLongs > 0)
{
for(i = 0;i < surplusLongs; i++)
{
//把不够的部分模拟补上
data[hasLongs++] = 0x00;
}
fwrite(data,sizeof(char),46,fileOut); //写入数据
endjwy = ftell(fileOut); //记录开插入校验码的位置
//添加辅助检验字段
fputc(0x00,fileOut);
dataNum = short(ftell(fileOut)) - (short)startjyw; //计算检验的字段长度
}
else
{
//多于或者等于46B,则正常读取
fwrite(data,sizeof(char),pyl - lastDataPacket,fileOut);
//记录开插入校验码的位置
endjwy = ftell(fileOut);
fputc(0x00,fileOut);
dataNum = short(ftell(fileOut)) - (short)startjyw;
}
}
fseek(fileOut,(short)startjyw,SEEK_SET); //将读指针指向开始校验的位置unsigned char crc = 0;
int statusNum = dataNum;
while(statusNum--)
{
char temp;
//读1B的数据
temp = fgetc(fileOut);
//模拟数据除的二进制除法过程
for(unsigned char i = (unsigned char)0x80; i > 0;i >>= 1)
{
if(crc & 0x80)
{ //当前余数最高位为1,需要进行除法运算。
crc <<= 1;
//将输入数据相应位的值递补到余数末位
if(temp & i)
{
crc ^= 0x01;
}
//进行除法运算,即与除数的低位相异或。
crc ^= 0x07;
}
else
{
crc <<= 1; //crc左移位,最低位补。
//输入数据相应位的值递补到余数末位
if(temp & i) crc ^= 0x01;//将输入数据相应位的值递补到余数末位。
}
}
}
//将读指针指尾部,开始插入检验字段
fseek(fileOut,(short)endjwy,SEEK_SET);
//若不足4B,补位至4B
printf("\n帧的校验和:");
if(sizeof(crc) == 1)
{
fputc(0x00,fileOut);
fputc(0x00,fileOut);
fputc(0x00,fileOut);
printf("%X %X %X ",0x00,0x00,0x00);
printf("%X ",crc);
fputc(crc,fileOut);
}
else if(sizeof(crc) == 2)
{
fputc(0x00,fileOut);
fputc(0x00,fileOut);
printf("%X %X ",0x00,0x00);
printf("%X ",crc);
fputc(crc,fileOut);
}
else
{
fputc(0x00,fileOut);
printf("%X ",0x00);
printf("%X ",crc);
fputc(crc,fileOut);
}
printf("\n帧的数据部分:");
for(int m = 0; m < dataNum - 15; m++)
{
printf("%X ",data[m]);
}
printf("\n");
}
//关闭文件资源
fclose(fileIn);
fclose(fileOut);
return 0;
}
//程序主函数
int main()
{
int num;
char fileinput[20]; //记录地址
while(1)
{
printf("%s"," 1.帧封装,2.退出\n");
printf("*******************************************************************************\n");
printf("%s","请输入1 or 2:");
scanf("%d",&num);
switch(num)
{
case 1:
//帧封装调用
printf("请输入文件路径:");
scanf("%s",fileinput);
zhenfengzhuang(fileinput);
break;
case 2:
exit(0);
default:
putchar('\a');
printf("%s","你可以选择输入1 or 2!\n");
}
printf("\n\n");
}
return 0;
}。