复习用 #include "sysinclude.h" #include <deque> using namespace std; extern void SendFRAMEPacket(unsigned char* pData, unsigned int len); #define WINDOW_SIZE_STOP_WAIT 1 #define WINDOW_SIZE_BACK_N_FRAME 4 typedef enum {data,ack,nak} frame_kind; typedef struct frame_head { frame_kind kind; //帧类型 unsigned int seq; //序列号 unsigned int ack; //确认号 unsigned char data[100]; //数据 }; typedef struct frame { frame_head head; //帧头 unsigned int size; //数据的大小 }; // 需要定义另外一个数据结构来存帧和其大小 typedef struct mainFrame { frame* f; int size; }; deque<mainFrame> stop_wait_send_queue; //停等式协议发送队列 deque<mainFrame> backn_send_queue; //回退N式协议发送队列 deque<mainFrame> choice_send_queue; //选择性重传式协议发送队列 bool full = false; //标记停等式时窗口是否为空 int current_window_size = 0; //回退N的当前窗口大小 int current_window_size_c = 0; //选择性重传式的当前窗口大小 /* * 停等协议测试函数 */ int stud_slide_window_stop_and_wait(char *pBuffer, int bufferSize, UINT8 messageType) { unsigned int ack; unsigned int seq; mainFrame temp; mainFrame send; mainFrame receive; if (messageType == MSG_TYPE_SEND) { temp.f = new frame; (*temp.f) = *(frame*)pBuffer; temp.size = bufferSize; stop_wait_send_queue.push_back(temp); //将发送数据封装后压入发送队列,下同 if ( full == false) //窗口不为空时发送 { full = true; //关闭窗口 send = stop_wait_send_queue.front(); SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } if (messageType == MSG_TYPE_RECEIVE) { ack = ((frame *)pBuffer)->head.ack; if (stop_wait_send_queue.size()!=0) { receive = stop_wait_send_queue.front(); if( ack == (receive.f)->head.seq ) //找到对应ack的帧,关闭该窗口 { stop_wait_send_queue.pop_front(); if (stop_wait_send_queue.size()!=0) { send = stop_wait_send_queue.front(); //等待队列中还有数据的话打开新窗口发送 SendFRAMEPacket(((unsigned char*)send.f), send.size); } } } else { full = false; //接收队列为空则打开新窗口 } return 0; } if (messageType == MSG_TYPE_TIMEOUT) { seq = ntohl(*(unsigned int*)pBuffer); send = stop_wait_send_queue.front(); //超时重发队列头部的帧 if ( seq == send.f->head.seq ) { SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } return 0; } /* * 回退n帧测试函数 */ int stud_slide_window_back_n_frame(char *pBuffer, int bufferSize, UINT8 messageType) { unsigned int ack; unsigned int seq; mainFrame temp; mainFrame send; mainFrame receive; int current_frame; int i; if ( messageType == MSG_TYPE_SEND) { temp.f = new frame; (*temp.f) = *(frame*)pBuffer; temp.size = bufferSize; backn_send_queue.push_back(temp); if ( current_window_size < WINDOW_SIZE_BACK_N_FRAME) //发送窗口未满时继续发送 { current_window_size++; send = backn_send_queue.back(); SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } if (messageType == MSG_TYPE_RECEIVE) { ack = ((frame *)pBuffer)->head.ack; for (current_frame=0; current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < backn_send_queue.size(); current_frame++) { receive = backn_send_queue[current_frame]; //接受ack及之前的帧 if (ack == receive.f->head.seq) break; } if (current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < backn_send_queue.size()) { for (i = 0; i <= current_frame; i++) //关闭接收完毕的帧对应的窗口 { backn_send_queue.pop_front(); current_window_size--; } } for (i=current_window_size; i < WINDOW_SIZE_BACK_N_FRAME && i < backn_send_queue.size() && current_window_size < WINDOW_SIZE_BACK_N_FRAME; i++) { current_window_size++; //接收完毕后窗口前移,继续发送 send = backn_send_queue[i]; SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } if (messageType == MSG_TYPE_TIMEOUT) { seq = ntohl(*(unsigned int*)pBuffer); for (current_frame=0; current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < backn_send_queue.size(); current_frame++) { send = backn_send_queue[current_frame]; if (seq == send.f->head.seq) //找到重发的帧在队列中的位置 break; } for (i=current_frame; i < WINDOW_SIZE_BACK_N_FRAME && i < backn_send_queue.size(); i++) { send = backn_send_queue[i]; //重发其后所有帧 SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } return 0; } /* * 选择性重传测试函数 */ int stud_slide_window_choice_frame_resend(char *pBuffer, int bufferSize, UINT8 messageType) { unsigned int ack; unsigned int seq; mainFrame temp; mainFrame send; mainFrame receive; int current_frame; int i; if (messageType == MSG_TYPE_SEND) //发送部分和回退n的是一样的 { temp.f = new frame; (*temp.f) = *(frame*)pBuffer; temp.size = bufferSize; choice_send_queue.push_back(temp); if ( current_window_size < WINDOW_SIZE_BACK_N_FRAME) { current_window_size++; send = choice_send_queue.back(); SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } if (messageType == MSG_TYPE_RECEIVE) { frame_kind frame_type = (frame_kind) ntohl(((frame*)pBuffer)->head.kind); //获取帧的类型 ack = ((frame *)pBuffer)->head.ack; if (frame_type == nak) //若是nak,则重发对应帧 { for (current_frame=0; current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < choice_send_queue.size(); current_frame++) { receive = choice_send_queue[current_frame]; if (ack == receive.f->head.seq) { send = choice_send_queue[current_frame]; SendFRAMEPacket(((unsigned char*)send.f), send.size); break; } } return 0; } else { //否则是ack的话和回退n的类似 for (current_frame=0; current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < choice_send_queue.size(); current_frame++) { receive = choice_send_queue[current_frame]; if (ack == receive.f->head.seq) break; } if (current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < choice_send_queue.size()) { for (i = 0; i <= current_frame; i++) { choice_send_queue.pop_front(); current_window_size--; } } for (i=current_window_size; i < WINDOW_SIZE_BACK_N_FRAME && i < choice_send_queue.size() && current_window_size < WINDOW_SIZE_BACK_N_FRAME; i++) { current_window_size++; send = choice_send_queue[i]; SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } return 0; } if (messageType == MSG_TYPE_TIMEOUT) //超时重发的机制和回退n的类似 { seq = ntohl(*(unsigned int*)pBuffer); for (current_frame=0; current_frame < WINDOW_SIZE_BACK_N_FRAME && current_frame < choice_send_queue.size(); current_frame++) { send = choice_send_queue[current_frame]; if (seq == send.f->head.seq) break; } for (i=current_frame; i < WINDOW_SIZE_BACK_N_FRAME && i < choice_send_queue.size(); i++) { send = choice_send_queue[i]; SendFRAMEPacket(((unsigned char*)send.f), send.size); } return 0; } return 0; }