滑动窗口协议实验


//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;
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值