卫生室六室分开:关于帧封装的编程的问题

来源:百度文库 编辑:查人人中国名人网 时间:2024/04/29 13:52:41
这是我们课程设计的题目,有那位高人能帮帮我吗?
编写程序,根据给出的原始数据,组装一个IEEE 802.3格式的帧(题目默认的输入文件为二进制原始数据)。
要求程序为命令行程序。如:可执行文件名为framer.exe,则命令行形式如下:
framer inputfile outputfile
其中,inputfile为原始数据文件,outputfile为输出结果。
使用的操作系统、语言和编译环境不限.
我需要的是源代码!!!开发语言不限.

#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#include "io.h"
#include "fcntl.h"
#include "string.h"
#include "alloc.h"
#define BUFFER_MAX 1500
#define BUFFER_MIN 46
#define PREAMBLE_LEN 8
#define DEST_LEN 6
#define SOURCE_LEN 6
#define FLIE_LENGTH_LEN 2
#define FCS_LEN 4
char preamble[8]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5};/* 前导码 */
char addr_dest[6]={0x0,0x0,0x0,0x0,0x0,0x0};
char addr_source[6]={0x0,0x0,0x0,0x0,0x0,0x0};
long *fcs;
char *fill_data;
char *infilename[10];
char *outfilename[10];
void fill(int x); /*填充函数 */
void framer();
void init_crc32_table();
void GenerateCRC32(char* DataBuf,unsigned long len);
unsigned long crc32_table[256];
unsigned long ulPolynomial = 0x04c11db7;
void main(int argc,char *argv[]) /* 主函数 */
{
clrscr();
if(argc<3)
{
printf("command number error!");

}
stpcpy(infilename,argv[1]);
stpcpy(outfilename,argv[2]);
init_crc32_table();
framer();
printf("framer success!");
getch();
}

void framer() /* 封装函数 */
{
char *buff_p;
unsigned int buff_length;
int read_handle,write_handle; /* 声明文件句柄 */
long file_back,file_length;
long file_offset;
int conditional=1;
int * c;
if((read_handle=open(infilename,O_BINARY|O_RDONLY))<0) /* 以只读方式打开文件,并返回句柄 */
printf("open input file error!");
if((write_handle=open(outfilename,O_BINARY|O_WRONLY|O_CREAT))<0) /* 以只写方式打开文件,并返回句柄 */
printf("open output file error!");
file_length=filelength(read_handle); /*文件长度*/
file_back=file_length; /*file_back是文件剩余读取长度*/
while(conditional) /* 循环取数据,直到文件尾 */
{

file_offset=file_length-file_back; /*文件当前位置*/
file_offset=lseek(read_handle,file_offset,SEEK_SET);
if(file_back>BUFFER_MAX)
{
buff_length=PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+BUFFER_MAX+FCS_LEN; /*定义缓冲区长度*/
buff_p=(char *) malloc(buff_length);
memcpy(buff_p,preamble,PREAMBLE_LEN); /* 缓冲区加入前导码和界定符 */
memcpy(buff_p+PREAMBLE_LEN,addr_dest,DEST_LEN); /* 加入目的地址 */
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN,addr_source,SOURCE_LEN); /* 加入源地址 */
*c=BUFFER_MAX&0xFFFF;
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN,c,FLIE_LENGTH_LEN); /* 加入长度字段 */
read(read_handle,buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN,BUFFER_MAX); /* 加入数据 */
GenerateCRC32(buff_p+PREAMBLE_LEN,DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+BUFFER_MAX);
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+BUFFER_MAX,fcs,FCS_LEN); /* 加入效验码 */
write(write_handle,buff_p,buff_length);
file_back=file_back-BUFFER_MAX;
conditional=1;

}

else if(file_back<BUFFER_MIN)
{

buff_length=PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+BUFFER_MIN+FCS_LEN;
buff_p=(char *) malloc(buff_length);
memcpy(buff_p,preamble,PREAMBLE_LEN);
memcpy(buff_p+PREAMBLE_LEN,addr_dest,DEST_LEN);
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN,addr_source,SOURCE_LEN);
*c=file_back&0xFFFF;
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN,c,FLIE_LENGTH_LEN);
read(read_handle,buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN,(unsigned)file_back);
fill(BUFFER_MIN-file_back);
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+file_back,fill_data,(unsigned)(BUFFER_MIN-file_back)); /* 加入填充码 */
GenerateCRC32(buff_p+PREAMBLE_LEN,DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+BUFFER_MIN);
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+BUFFER_MIN,fcs,FCS_LEN);
write(write_handle,buff_p,buff_length);
conditional=0;
free(fill_data);
}
else
{
buff_length=PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+file_back+FCS_LEN;
buff_p=(char *) malloc(buff_length);
memcpy(buff_p,preamble,PREAMBLE_LEN);
memcpy(buff_p+PREAMBLE_LEN,addr_dest,DEST_LEN);
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN,addr_source,SOURCE_LEN);
*c=file_back&0XFFFF;
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN,c,FLIE_LENGTH_LEN);
read(read_handle,buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN,(unsigned)file_back);
GenerateCRC32(buff_p+PREAMBLE_LEN,DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+file_back);
memcpy(buff_p+PREAMBLE_LEN+DEST_LEN+SOURCE_LEN+FLIE_LENGTH_LEN+file_back,fcs,FCS_LEN);
write(write_handle,buff_p,buff_length);
conditional=0;
}
}
free(buff_p);
close(read_handle);
close(write_handle);
}

void fill(int x)
{

fill_data=(char *) malloc(x);
setmem(fill_data,x,0x0); /* 函数未完成,测试使用 */
}
void GenerateCRC32(char* DataBuf,unsigned long len)
{
unsigned long oldcrc32;
unsigned long crc32;
unsigned long oldcrc;
unsigned int charcnt;
char crc_c,t;
oldcrc32 = 0x00000000; /*初值为0 */
charcnt=0;
while (len--) {
t= (oldcrc32 >> 24) & 0xFF; /* 要移出的字节的值 */
oldcrc=crc32_table[t]; /* 根据移出的字节的值查表 */
crc_c=DataBuf[charcnt]; /* 新移进来的字节值 */
oldcrc32= (oldcrc32 << 8) | crc_c; /* 将新移进来的字节值添在寄存器末字节中 */
oldcrc32=oldcrc32^oldcrc; /* 将寄存器与查出的值进行xor运算 */
charcnt++;
}
crc32=oldcrc32;
*fcs=crc32;
}

unsigned long Reflect(unsigned long ref, char ch)
{
unsigned long value=0;
int i;
/* 交换bit0和bit7,bit1和bit6,类推 */
for(i=1;i < (ch+1);i++)
{
if(ref & 1)
value |= value << (ch - i);
ref >>= 1;
}
return value;
}

void init_crc32_table()
{
unsigned long temp_crc;
int i;
int j;
/* 256个值 */
for(i = 0; i <= 0xFF; i++)
{
temp_crc=Reflect(i, 8);
crc32_table[i]= temp_crc<< 24;
for (j = 0; j < 8; j++)
{
unsigned long t1,t2;
unsigned long flag=crc32_table[i]&0x80000000;
t1=(crc32_table[i] << 1);
if(flag==0)
t2=0;
else
t2=ulPolynomial;
crc32_table[i] =t1^t2 ;
}
crc32_table[i] = Reflect(crc32_table[i], 32);
}
}


帧封装只是在数据的头和尾上加特定的二进制数据,可以直接用读写二进制文件的方式读出来,然后把该加的头尾写进去就行了。
IEEE 802.3格式的帧
前导(Preambl)
帧起始定界符/同步(Start Frame Delimiter,SFD)/Synch
目的地址(Destination Address,DA)
源地址(Source Address,SA)
长度(Length)或类型(Type)字段
数据(Data)
帧效验序列(Frame Check Sequence,FCS)

除了帧效验序列稍微复杂点,其他的都很简单的,多看看书啊。

帧封装只是在数据的头和尾上加特定的二进制数据,可以直接用读写二进制文件的方式读出来,然后把该加的头尾写进去就行了。
IEEE 802.3格式的帧
前导(Preambl)
帧起始定界符/同步(Start Frame Delimiter,SFD)/Synch
目的地址(Destination Address,DA)
源地址(Source Address,SA)
长度(Length)或类型(Type)字段
数据(Data)
帧效验序列(Frame Check Sequence,FCS)

帧封装只是在数据的头和尾上加特定的二进制数据,可以直接用读写二进制文件的方式读出来,然后把该加的头尾写进去就行了。
IEEE 802.3格式的帧
前导(Preambl)
帧起始定界符/同步(Start Frame Delimiter,SFD)/Synch
目的地址(Destination Address,DA)
源地址(Source Address,SA)
长度(Length)或类型(Type)字段
数据(Data)
帧效验序列(Frame Check Sequence,FCS)

除了帧效验序列稍微复杂点,其他的都很简单的,多看看书啊。

帧封装只是在数据的头和尾上加特定的二进制数据,可以直接用读写二进制文件的方式读出来,然后把该加的头尾写进去就行了。
IEEE 802.3格式的帧
前导(Preambl)
帧起始定界符/同步(Start Frame Delimiter,SFD)/Synch
目的地址(Destination Address,DA)
源地址(Source Address,SA)
长度(Length)或类型(Type)字段
数据(Data)
帧效验序列(Frame Check Sequence,FCS)

帧封装只是在数据的头和尾上加特定的二进制数据,可以直接用读写二进制文件的方式读出来,然后把该加的头尾写进去就行了。
IEEE 802.3格式的帧
前导(Preambl)
帧起始定界符/同步(Start Frame Delimiter,SFD)/Synch
目的地址(Destination Address,DA)
源地址(Source Address,SA)
长度(Length)或类型(Type)字段
数据(Data)
帧效验序列(Frame Check Sequence,FCS