Go Back N C语言实现(无ACK)
来源:互联网 发布:卫视直播软件下载 编辑:程序博客网 时间:2024/06/06 14:28
#include <stdio.h>#include <string.h>#include "protocol.h"#include "datalink.h"#define MAX_SEQ 6#define DATA_TIMER 2600#define inc(k) if(k<MAX_SEQ) k=k + 1;else k = 0typedef struct//定义数据包packet {unsigned char data[PKT_LEN];}packet; typedef enum {true,false} boolean ;typedef unsigned int seq_nr ;typedef struct//定义帧frame{ unsigned char kind;// FRAME_DATA unsigned char ack; unsigned char seq; unsigned char data[PKT_LEN]; unsigned int padding;} frame ;static int phylsical_ready = 0;//物理层是否准备好的标志,为1表示物理层已准备好,为0表示物理层没准备好.seq_nr next_frame_to_send=0;seq_nr ack_expected=0;seq_nr frame_expected=0;seq_nr nbuffered = 0;//正在用的缓存frame f;seq_nr i;packet buffer[MAX_SEQ+1];int event,arg,len;//事件,帧长度static boolean between(seq_nr a, seq_nr b, seq_nr 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); phylsical_ready = 0;}static void send_data(seq_nr frame_nr,seq_nr frame_expected,packet buffer[]){frame f;f.kind = FRAME_DATA;//帧的类型f.seq = frame_nr;//给帧加序号f.ack = ( frame_expected + MAX_SEQ ) % ( MAX_SEQ + 1 ) ;//捎带确认memcpy(f.data, buffer[frame_nr].data, PKT_LEN);//将buffer[frame_nr]中的数据拷贝到s.data中dbg_frame("Send DATA %d %d, ID %d\n", f.seq, f.ack, *(short *)f.data);put_frame( (unsigned char *)&f, 3 + PKT_LEN ); //传输帧start_timer(frame_nr, DATA_TIMER); //启动计时器 }int main(int argc,char **argv){protocol_init(argc, argv);lprintf("Designed by nancyyihao, build: " __DATE__" "__TIME__"\n");disable_network_layer();while(1){event = wait_for_event(&arg);switch(event){case NETWORK_LAYER_READY:get_packet( buffer[next_frame_to_send].data );//收到一个新的packet //lprintf("Send DATA %d\n",sizeof(buffer[next_frame_to_send].data)/ sizeof(buffer[next_frame_to_send].data[0]) );nbuffered = nbuffered + 1 ;send_data(next_frame_to_send, frame_expected,&buffer);inc(next_frame_to_send);//发送者窗口前移(上限前移)break;case PHYSICAL_LAYER_READY:phylsical_ready = 1;break;case FRAME_RECEIVED: len = recv_frame((unsigned char *)&f, sizeof f);//从物理层取数据 if (len < 5 || (crc32((unsigned char *)&f, len) != 0)) {dbg_event("**** Receiver Error, Bad CRC Checksum\n");break; } if (f.kind == FRAME_DATA){dbg_frame("Recv DATA %d %d, ID %d\n", f.seq, f.ack, *(short *)f.data);//lprintf("Recv DATA %d\n",sizeof(f.data) / sizeof(f.data[0]));if(f.seq == frame_expected)//收到了期待的帧{put_packet(f.data, len-7);//上交数据给网络层inc(frame_expected);//接收方窗口前移(下限前移)}}while(between(ack_expected, f.ack, next_frame_to_send))//处理捎带确认{nbuffered = nbuffered - 1 ;stop_timer(ack_expected);//收到帧,计时器停止inc(ack_expected);//缩小发送者窗口}break;case DATA_TIMEOUT:dbg_event("---- DATA %d timeout\n", arg) ; next_frame_to_send = ack_expected ;//开始重传for( i=1 ; i <= nbuffered ; i++ ){send_data(next_frame_to_send, frame_expected,&buffer);//重传inc(next_frame_to_send);//准备下一个要传的dd帧}break;}if( ( nbuffered < MAX_SEQ ) && phylsical_ready )enable_network_layer();elsedisable_network_layer();}}
0 0
- Go Back N C语言实现(无ACK)
- Go Back N C语言(有ACK)
- 编程实现可靠数据传输原理Go-Back-N
- a good example my call back(c语言实现)
- N!C语言实现
- n个数的全排列C语言递归 (回溯)back-tracking
- n! 的结果中包含多少个0(Go语言实现)
- 运输层协议:(2)Go-Back-N 协议
- C语言-对输入n个字符串进行排序(无导入string.h)
- C语言递归实现N宫格(九宫格)源码
- n阶行列式计算----c语言实现(完结)
- 【C语言】实现n^k(递归函数)
- C语言实现无头节点单链表
- GO 语言调用C函数(实例)
- C语言实现N皇后问题源代码
- N 皇后问题C语言实现
- C语言实现 N!的质因数分解
- c语言实现随机排列n个数
- 在Eclipse中运行第一个MapReduce程序
- c++ 全排列
- 计算机网络总结(上)
- .net micro framework的入门例程-点灯神话-4.加入闪烁LED函数
- 计算机网络总结(下)
- Go Back N C语言实现(无ACK)
- 跟踪OpenLDAP服务器性能
- STM32 串行通信 USART 程序例举
- 最小树形图 UVA 11183 Teen Girl Squad
- .net micro framework的入门例程-点灯神话-5.加入一个线程闪烁LED
- rmq的st算法模板题 nyoj 119
- nefu 625 Page Replacement
- Go Back N C语言(有ACK)
- spring webservice (二) 客户端开发