這周做計算機網絡課程設計,在幾個題目中選了個MAC幀的封裝.
首先看最後結果:
這裡有個bug,不知道為什麼幀前導碼和幀定界符前多了FFFFFF,我自己沒搞懂???
程序如下:
- /*
- 目標:
- 封裝
- 1.將inputFile文件中的數據封裝成MAC幀,封裝好的MAC幀寫入outputFile文件中.
- 2.如果數據長度小於46字節,則補全到46字節
- 3.如果數據長度大於1500,則封裝成多個MAC幀
- 解封裝:
- 讀取outputFile中的數據,並逐個顯示幀的信息
-
- 其實我們要求還是蠻低的,上面有好多是自己添加的
- */
- #include <stdio.h>
- #include <stdlib.h>
- #define MAXSIZE 1500
- #define echo(format,str) printf("%"#format,str)
- #define inputFile "inputFile.txt"
- #define outputFile "outputFile.txt"
- void flush()
- {
- fflush(stdin);
- fflush(stdout);
- }
-
-
- unsigned int crc8(unsigned char *ptr,unsigned int len)
- /*
- CRC校驗,ptr是需要計算的數組首地址,len是需要計算的長度
- */
- {
- unsigned int CRC = 0;
- unsigned int i;
-
- while(len--){
- CRC = CRC^ *ptr++;
- for(i = 0; i < 8; i++){
- if(CRC & 0x01){
- CRC = (CRC >> 1 )^ 0x8c;
- }
- else{
- CRC >>= 1;
- }
- }
- }
-
- return CRC;
- }
-
-
- int encapsulation()
- /*幀封裝函數*/
- {
- int i,dataCrc,nu,j,lastNu,sum;
- FILE *fpIn,*fpOut;
- int src[6],des[6];
- char type[2],data[MAXSIZE];
- if((fpIn=fopen(inputFile,"a+"))==NULL)
- {
- echo(s,"打開文件失敗!");
- return 1;
- }
- if((fpOut=fopen(outputFile,"wb"))==NULL)
- {
- echo(s,"寫入文件失敗");
- return 1;
- }
-
- fseek(fpIn,0,SEEK_END);
- sum=ftell(fpIn);
- nu=sum/1500;
- if((sum-nu*1500)<46)
- {
- for(i=0;i<(46-(sum-nu*1500));i++)
- fputc(0x0,fpIn); //如果不足,則填充
- }
-
- rewind(fpIn);
-
- echo(s,"請輸源MAC:");
- scanf("%x-%x-%x-%x-%x-%x",src,src+1,src+2,src+3,src+4,src+5);
- fflush(stdin);
- echo(s,"請輸入目標MAC:");
- scanf("%x-%x-%x-%x-%x-%x",des,des+1,des+2,des+3,des+4,des+5);
- flush();
- echo(s,"請輸入類型字段:");
- flush();
- scanf("%2x%2x",type,type+1);
-
- for(j=0;j<nu+1;j++)
- {
- for(i=0;i<7;i++)
- fputc(0xaa,fpOut); //寫入幀前導碼
- fputc(0xab,fpOut); //寫入幀定界符
-
- for(i=0;i<6;i++)
- {
- fputc(des[i],fpOut); //寫入目的MAC
- }
- for(i=0;i<6;i++)
- {
- fputc(src[i],fpOut); //寫入源MAC
- }
-
- fputc(type[0],fpOut); //寫入類型號
- fputc(type[1],fpOut);
-
-
- if(j!=nu)
- /*不是最後一個數據,則前面的數據都應該是1500*/
- {
- fread(data,sizeof(char),1500,fpIn);
- fwrite(data,sizeof(char),1500,fpOut);
- dataCrc=crc8(data,1500);
- fputc(dataCrc,fpOut);
- }
- else
- {
- //最後一段數據,需要額外處理,獲取長度
- lastNu=ftell(fpIn);
- fread(data,sizeof(char),sum-lastNu,fpIn);
- fwrite(data,sizeof(char),sum-lastNu,fpOut);
- dataCrc=crc8(data,sum-lastNu);
- fputc(dataCrc,fpOut);
- }
- }
-
- fclose(fpIn);
- fclose(fpOut);
-
- echo(s,"\n\n");
-
- return 0;
- }
-
-
- int unPack()
- /*解封裝函數*/
- {
- int i,dataStart,dataEnd,srcCrc,nowCrc,dataLength,frameNu=0,sum,j;
- char c,data[MAXSIZE];
- FILE *fpOut;
- if((fpOut=fopen(outputFile,"rb"))==NULL)
- {
- echo(s,"打開文件失敗!");
- return 1;
- }
-
- fseek(fpOut,0,SEEK_END);
- sum=ftell(fpOut);
- rewind(fpOut);
-
- while(1)
- /*此循環為了獲取幀的個數
- 主要思路:連續7個0xaa,第8個是0xab
- */
- {
- if(ftell(fpOut)>=sum)
- {
- break;
- }
- for(i=0;i<7;i++)
- {
- if(ftell(fpOut)>=sum)
- {
- break;
- }
-
- if(fgetc(fpOut)!=0xaa)
- {
- i=-1;
- }
- }
- if(ftell(fpOut)>=sum)
- {
- break;
- }
- if(fgetc(fpOut)==0xab)
- {
- ++frameNu;
- }
- }
- rewind(fpOut);
-
- for(j=0;j<frameNu;j++)
- /*循環逐個輸出幀的信息*/
- {
- printf("\n\n幀序號: %d\n\n",j+1);
- echo(s,"幀前導碼: ");
- for (i=0;i<7;i++)
- {
- c=fgetc(fpOut);
- echo(.2X,c);
- }
- echo(s,"\n\n");
-
- echo(s,"幀前定界符: ");
- {
- c=fgetc(fpOut);
- echo(.2X,c);
- }
-
- echo(s,"\n\n");
-
- echo(s,"目的MAC地址: ");
- for (i=0;i<6;i++)
- {
- c=fgetc(fpOut);
- echo(.2X,c);
- if (i!=5)
- echo(s,"-");
- }
- echo(s,"\n\n");
-
- echo(s,"源MAC地址: ");
- for (i=0;i<6;i++)
- {
- c=fgetc(fpOut);
- echo(.2X,c);
- if (i!=5)
- echo(s,"-");
- }
- echo(s,"\n\n");
-
- echo(s,"類型號: ");
-
- c=fgetc(fpOut);
- echo(.2X,c);
- c=fgetc(fpOut);
- echo(.2X,c);
-
- if(j!=frameNu-1)
- //不是最後一個幀,則數據長度都是1500
- {
- fread(data,sizeof(char),1500,fpOut);
- srcCrc=fgetc(fpOut);
- nowCrc=crc8(data,1500);
- }
- else
- {
- //最後一個幀,額外處理
- dataStart=ftell(fpOut);
- fseek(fpOut,-1,SEEK_END);
- dataEnd=ftell(fpOut)-1;
- dataLength=dataEnd-dataStart+1;
- srcCrc=fgetc(fpOut);
- fseek(fpOut,dataStart,SEEK_SET);
- fread(data,sizeof(char),dataLength,fpOut);
- nowCrc=crc8(data,dataLength);
- }
-
- printf("\n\n本次CRC: %d",nowCrc);
- echo(s,"\n\n行為: ");
- if (nowCrc==srcCrc) //比較CRC,是否出錯
- echo(s,"接受");
- else
- echo(s,"丟棄");
- printf(" 前次CRC:%d",srcCrc);
-
- }
- fclose(fpOut);
- echo(s,"\n\n");
- return 0;
- }
- void choice()
- {
- int choice;
- echo(s,"1.幀封裝\n");
- echo(s,"2.幀解析\n");
- echo(s,"3.退出\n");
- echo(s,"\t請選擇序號:");
- scanf("%d",&choice);
- switch(choice)
- {
- case 1:
- encapsulation();
- break;
- case 2:
- unPack();
- break;
- case 3:
- echo(s,"歡迎使用....\n");
- exit(0);
- default:
- putchar('\a');
- echo(s,"序號在1-3,請重新選擇\n");
-
- }
- }
- int main(int argc,char **argv)
- {
- while(1)
- {
-
- choice();
- echo(s,"\n");
- }
- return 0;
-
- }
總的說來,這個程序還是有很多很多需要修改的地方,健壯性很差,等有時間再好好完善一下.