//NetRiver平台上的一个实验,用c语言实验1比特滑动窗口协议、回退N帧协议和选择性重传协议
//使用队列实现
#include "sysinclude.h"
#include <deque>
extern void SendFRAMEPacket(unsigned char* pData, unsigned int len);
#define WINDOW_SIZE_STOP_WAIT 1
#define WINDOW_SIZE_BACK_N_FRAME 4
bool fullWin = false;
typedef enum {data, ack, nak} frame_kind;
typedef struct frame
{
frame_kind kind; //帧类型
unsigned int seq; //序列号
unsigned int ack; //确认号
unsigned char data[100]; //数据
};
typedef struct Buffer { //窗口中的帧
frame *pframe;
unsigned int size;
};
int back_n_frame_win = 0;
int choice_frame_resend_win = 0;
deque<Buffer> queue;
/*
* 停等协议测试函数
*/
int stud_slide_window_stop_and_wait(char *pBuffer, int bufferSize, UINT8 messageType)
{
Buffer buffer;
switch(messageType) {
case MSG_TYPE_TIMEOUT: { //某个帧超时
buffer = queue.front();
int serial;
serial = ntohl(*(unsigned int *)pBuffer);
//if(serial == ntohl(buffer.pframe->seq))
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
break;
}
case MSG_TYPE_SEND: { //系统要发送一个帧
buffer.pframe = new frame;
*buffer.pframe = *(frame *)pBuffer;
buffer.size = bufferSize;
queue.push_back(buffer); //放入队尾
if(fullWin == false) {
buffer = queue.front();
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
fullWin = true;
}
break;
}
case MSG_TYPE_RECEIVE: { //系统接收到一个帧的ACK
buffer = queue.front();
unsigned int ack;
ack = ntohl(((frame *)pBuffer)->ack);
if(ntohl(buffer.pframe->seq) == ack) { //发送序列号等于返回确认号
queue.pop_front();
buffer = queue.front();
fullWin = false;
if(queue.empty() == false) //发送队列存在等待发送的帧
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
fullWin = true;
}
break;
}
default:
return -1;
break;
}
return 0;
}
/*
* 回退n帧测试函数
*/
int stud_slide_window_back_n_frame(char *pBuffer, int bufferSize, UINT8 messageType)
{
Buffer buffer;
switch(messageType) {
case MSG_TYPE_TIMEOUT: { //某个帧超时
printf("timeout\n");
int serial;
serial = ntohl(*(unsigned int *)pBuffer);
int i;
for(i=0; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[i];
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
}
break;
}
case MSG_TYPE_SEND: { //系统要发送一个帧
buffer.pframe = new frame;
*buffer.pframe = *(frame *)pBuffer;
buffer.size = bufferSize;
queue.push_back(buffer); //放入队尾
//int i;
//for(i=back_n_frame_win; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[back_n_frame_win];
if(back_n_frame_win < WINDOW_SIZE_BACK_N_FRAME && back_n_frame_win < queue.size()) {
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
back_n_frame_win ++;
}
break;
}
case MSG_TYPE_RECEIVE: { //系统接收到一个帧的ACK
int i, j;
unsigned int ack;
ack = ntohl(((frame *)pBuffer)->ack);
for(i=0; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[i];
if(ntohl(buffer.pframe->seq) == ack) { //发送序列号等于返回确认号
for(j=0; j<=i; j++) {
queue.pop_front();
back_n_frame_win--;
//printf("back_n_frame_win is %d\n", back_n_frame_win);
}
for(j=back_n_frame_win; j<WINDOW_SIZE_BACK_N_FRAME && j<queue.size(); j++) {
buffer = queue[j];
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
back_n_frame_win++;
}
break;
}
}
break;
}
default:
return -1;
break;
}
return 0;
}
/*
* 选择性重传测试函数
*/
int stud_slide_window_choice_frame_resend(char *pBuffer, int bufferSize, UINT8 messageType)
{
Buffer buffer;
switch(messageType) {
case MSG_TYPE_TIMEOUT: { //某个帧超时
printf("timeout\n");
int serial;
serial = ntohl(*(unsigned int *)pBuffer);
int i;
for(i=0; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[i];
//if(serial == ntohl(buffer.pframe->seq))
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
}
break;
}
case MSG_TYPE_SEND: { //系统要发送一个帧
buffer.pframe = new frame;
*buffer.pframe = *(frame *)pBuffer;
buffer.size = bufferSize;
queue.push_back(buffer); //放入队尾
//int i;
//for(i=choice_frame_resend_win; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[choice_frame_resend_win];
if(choice_frame_resend_win < WINDOW_SIZE_BACK_N_FRAME && choice_frame_resend_win < queue.size()) {
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
choice_frame_resend_win ++;
}
break;
}
case MSG_TYPE_RECEIVE: { //系统接收到一个帧的ACK
int i, j;
unsigned int ack;
ack = ntohl(((frame *)pBuffer)->ack);
if(ntohl(((frame *)pBuffer)->kind) == nak) {
printf("nak\n");
for(i=0; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[i];
if(ntohl(buffer.pframe->seq) == ack) {
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
break;
}
}
}
else {
for(i=0; i<WINDOW_SIZE_BACK_N_FRAME && i<queue.size(); i++) {
buffer = queue[i];
if(ntohl(buffer.pframe->seq) == ack) { //发送序列号等于返回确认号
for(j=0; j<=i; j++) {
queue.pop_front();
choice_frame_resend_win--;
}
for(j=choice_frame_resend_win; j<WINDOW_SIZE_BACK_N_FRAME && j<queue.size(); j++) {
buffer = queue[j];
SendFRAMEPacket((unsigned char *)buffer.pframe, buffer.size);
choice_frame_resend_win++;
}
break;
}
}
}
break;
}
default:
//return -1;
break;
}
return 0;
}