C语言ack是什么字符,Go Back N C语言(有ACK)

本文介绍了一个简易数据链路层协议的实现过程,包括帧结构定义、发送接收流程控制及错误检测机制等核心内容。该协议通过定时器与确认帧确保数据可靠传输。

#include

#include

#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

{

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();

}

}

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值