分享
  1. 首页
  2. 文章

Go Back N C语言(有ACK)

jasonkent27 · · 4052 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


#include <stdio.h>
#include <string.h>
#include "protocol.h"
#include "datalink.h"
#define DATA_TIMER 3000
#define ACK_TIMER 1500
#define MAX_SEQ 7
void inc(unsigned char* number)
{
	(*number)++;
	if(*number==MAX_SEQ+1)
	*number=0;
}
struct FRAME { 
 unsigned char kind; /* FRAME_DATA */
 unsigned char ack;
 unsigned char seq;
 unsigned char data[PKT_LEN]; 
 unsigned int padding;
};
struct ACK_FRAME { 
 unsigned char kind; /* FRAME_DATA */
 unsigned char ack;
 unsigned int padding;
};
static unsigned char frame_nr = 0;	//next frame to send
static unsigned char ack_expected = 0; 
static unsigned char buffer[MAX_SEQ+1][PKT_LEN];	//
static unsigned char nbuffered = 0;					//缓冲区大小	
static unsigned char frame_expected = 0;
static int phl_ready = 0;
static void put_frame(unsigned char *frame, int len)
{
 *(unsigned int *)(frame + len) = crc32(frame, len);
 send_frame(frame, len + 4);
 phl_ready = 0;
}
static void send_data_frame(void)
{
 struct FRAME s;
 s.kind = FRAME_DATA;
 s.seq = frame_nr;
	s.ack = (frame_expected+MAX_SEQ)%(MAX_SEQ+1);		// 另一端的ack
	memcpy(s.data, buffer[frame_nr], PKT_LEN);
 dbg_frame("Send DATA %d %d, ID %d\n", s.seq, s.ack, *(short *)s.data);
 put_frame((unsigned char *)&s, 3 + PKT_LEN);
 start_timer(frame_nr, DATA_TIMER);
	stop_ack_timer();
}
static void send_ack_frame(void)
{
 struct ACK_FRAME s;
 s.kind = FRAME_ACK;
 s.ack = (frame_expected+MAX_SEQ)%(MAX_SEQ+1);
 dbg_frame("Send ACK %d\n", s.ack);
 put_frame((unsigned char *)&s, 2);
	stop_ack_timer();
}
int BetweenAN(unsigned char a , unsigned char b , unsigned char c)
{
	if(((a<=b)&&(b<c))||((c<a)&&(a<=b))||((b<c)&&(c<a)))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
int main(int argc, char **argv)
{
 int event, arg;
 struct FRAME f;
 int len = 0;
	unsigned char i;
 protocol_init(argc, argv); 
 lprintf("Designed by Jiang Yanjun, build: " __DATE__" "__TIME__"\n");
	lprintf("The argc is: %d , the argv is: %s\n",argc,*argv);
 disable_network_layer();
 for (;;) {
 event = wait_for_event(&arg);
 switch (event) {
 case NETWORK_LAYER_READY:
			get_packet(buffer[frame_nr]); //取得数据
 nbuffered++;
 send_data_frame();
			inc(&frame_nr);	// next frame to send ++
 break;
 case PHYSICAL_LAYER_READY:
 phl_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;
 }
			else
			{
				if (f.kind == FRAME_ACK) 
					dbg_frame("Recv ACK %d\n", f.ack);
				if (f.kind == FRAME_DATA) 
				{
					dbg_frame("Recv DATA %d %d, ID %d\n", f.seq, f.ack, *(short *)f.data);
					if (f.seq == frame_expected) 
					{
						dbg_frame("Recv DATA %d %d, ID %d\n put it to the NetWork\n", f.seq, f.ack, *(short *)f.data);
						put_packet(f.data, len - 7);
						inc(&frame_expected); // frame expected ++
						start_ack_timer(ACK_TIMER);
					}
					else
						dbg_frame("Recv DATA %d %d, ID %d\n but it won't be put\n", f.seq, f.ack, *(short *)f.data);
				}
					while(BetweenAN(ack_expected,f.ack,frame_nr))
					{
						nbuffered--;
						stop_timer(ack_expected);
						inc(&ack_expected);
					}
				
// send_ack_frame();
 } 
			
/* if (f.ack == frame_nr)
			{
 stop_timer(frame_nr);
 nbuffered--;
 frame_nr = 1 - frame_nr;
 }*/
 break; 
 case DATA_TIMEOUT:
 dbg_event("---- DATA %d timeout\n", arg); 
			frame_nr=ack_expected; //全部重发
			for(i=1;i<=nbuffered;i++)
			{
				send_data_frame();
				inc(&frame_nr);
			}
 break;
		case ACK_TIMEOUT:
			dbg_event("---- ACK %d timeout\n", arg); 
			send_ack_frame();
			break;
 }
		if (nbuffered < MAX_SEQ && phl_ready)
 enable_network_layer();
 else
 disable_network_layer();
 }
}



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:jasonkent27

查看原文:Go Back N C语言(有ACK)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
4052 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏