数据链路层选择重传协议不同于停等协议和go-backn,选择重传协议是接收方窗口是固定大小为(MAX_SEQ+1)/2
发送方窗口是0--(MAX_SEQ+1)/2,采用捎带确认,而且加入NAK,分别有两个计时器,ACK定时器和数据定时器
话不多说 上代码!!!!
#include <stdio.h>
#include <string.h>
#include "protocol.h"
#include "datalink.h"
#define DATA_TIMER 3000 //数据计时器
#define ACK_TIMER 1000 //ACK计时器
#define MAX_SEQ 31
#define NR_BUFS ((MAX_SEQ+1)/2)
typedef enum { false, true }boolean;//布尔变量
struct FRAME {
unsigned char kind; // FRAME_DATA ,FRAME_NAK ,FRAME_ACK
unsigned char ack;
unsigned char seq;
unsigned char data[PKT_LEN];
unsigned int padding;
};
boolean arrive[NR_BUFS];//标记接收缓冲区是否被占用
int no_nak = 1;//没有nak发送
static unsigned char nbuffered = 0;//当前发送缓存数目
static unsigned char in_buffer[NR_BUFS][PKT_LEN], out_buffer[NR_BUFS][PKT_LEN];//接收,发送缓存
static int phl_ready = 0;//表示物理层没就绪
static unsigned char ack_expected = 0, next_frame_to_send = 0;//发送窗口下界和上界
static unsigned char frame_expected = 0, too_far = NR_BUFS;//接收窗口下界和上界
static int between(unsigned char a, unsigned char b, unsigned char c)
{
return (((a <= b) && (b < c)) || ((c < a) && (a <= b)) || ((b < c) && (c < a)));
}
static void put_frame(unsigned char *frame, int len)
{
*(unsigned int *)(frame + len) = crc32(frame, len);
send_frame(frame, len + 4);
phl_ready &#