上一次解决编码问题,这里解决成帧问题。
在成帧的问题上,有很多需要解决的问题。首要的一点是:如何来定义数据的开头和结尾。
因为实验原因,这里采用最简单的方式:在数据的开头的结尾加入字节流01111110,在正式的数据内容中,凡是出现5个1,就在后面补一个0.
第一个难点:如何进行流量的控制?
这里同样采用最简单的停等协议。将帧按照0~7进行编号,在帧的前3位记录帧的编号。发送方发送第一个帧后,等待接收方的响应。如果超时,则重发。接收方收到消息后,发送需要的下帧的编号,如果超时没有得到响应,则重发。在确认第一帧发送完成后,发送方以后发送的内容只有得到确认才继续发送。
第二个难点:检错码
这里使用经常使用的CRC校验码。
实验本来不要求使用完全的程序控制。因此,我使用小程序完成专门的任务,然后使用bat或者shell脚本将小工具链接起来,达到智能的目的。
第一个是CRC的实现。我将常用的命令写到CRC.h的头文件中。
// CRC.h
#ifndef CRC_H
#define CRC_H
#define G_LENGTH 5
#include <stdio.h>
static short G[G_LENGTH] = {1, 0, 0, 1, 1};
short* getRemainder(short* frame, int length);
int getFileLength(FILE *fp);
#endif
实现如下:
// CRC.c
#include <stdio.h>
#include "CRC.h"
#include <malloc.h>
short* getRemainder(short* frame, int length)
{
int i, j, k;
short step[G_LENGTH];
short* remainder;
remainder = (short*)malloc(sizeof(short) * (G_LENGTH - 1));
for (i = 0; i < G_LENGTH; i++)
step[i] = frame[i];
for (i = 0; i < length - G_LENGTH + 1; i++)
{
if (step[0] == 0)
{
for (j = 0; j < 4; j++)
{
step[j] = step[j + 1] ^ 0;
}
}
else if (step[0] == 1)
for (j = 0; j < 4; j++)
step[j] = step[j + 1] ^ G[j + 1];
if (i < length - G_LENGTH)
step[4] = frame[i + 5];
}
for (i = 0; i < 4; i++)
remainder[i] = step[i];
return remainder;
}
int getFileLength(FILE *fp)
{
int length;
if (fp == NULL)
return -1;
fseek(fp, 0L, SEEK_END);
length = ftell(fp);
fseek(fp, 0L, SEEK_SET);
return length;
}
接下来是添加CRC校验码的实现(addcrc.c)