Go Back N C语言实现(无ACK)


#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 = 0

typedef 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)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模仿数据链路层的gobackn协议 /*该协议是搭载ack的回退n步协议*/ #include #include "protocol.h" #define max_seq 7 #define flag 126 #define ESC 100 #define wait_time 2700 //发送计时器等待的时间 #define ack_wait_time 280 static int phl_ready = 0; unsigned char buf[max_seq+1][270]; unsigned char ack[8]; //发送空的ack帧 unsigned char in_buf[600], last_buf[520];//接收时的缓冲区;去掉冗余之后的缓冲区,为防备因误码两帧合并为一帧而定义了很大一个数组 int nbuffered=0; //发送的帧数 int buf_size[max_seq+1]; //记下以发送各帧的帧长 int next_frame_to_send=0; int frame_in_phl=0; //用于成帧 int frame_expected=0; int ack_expected=0; int between(int a,int b,int c) { if( ((a<=b)&&(b<c)) || ((c<a)&&(a<=b)) || ((b<c)&&(c<a)) ) return 1; else return 0; } //判断帧尾,防止出现误判esc esc flag为数据的情况 int end_flag(int in_len) { int count=0; int i; if(in_len=0;i--)//记录flag前的esc数目 count++; return count%2; //若flag前的esc为偶数,则为帧尾 }//成帧函数--数据帧 void send_frame(char *my_buf,int len) { int n; buf[frame_in_phl][0]=(frame_expected+max_seq)%(max_seq+1); //ack buf[frame_in_phl][1]=frame_in_phl; //发送帧的帧号 for(n=0;n<len;n++) buf[frame_in_phl][n+2]=my_buf[n]; //将处理过的新帧赋值到缓冲区中 len=len+2; *(unsigned int *)(buf[frame_in_phl]+len) = crc32(buf[frame_in_phl],len); //在原始帧的基础上加检验和 buf_size[frame_in_phl]=len+4; //记录当前帧的长度,包括3个帧头,4个检验和 nbuffered=nbuffered+1; //缓冲区占用数加一 frame_in_phl=(frame_in_phl+1)%(max_seq+1); } //成帧函数--ack帧 void send_ack() //ack帧的处理 { ack[0]=(frame_expected+max_seq)%(max_seq+1); ack[1]=max_seq+10; //ack帧的序号位,使ack[1]==frame_expected恒不成立 *(unsigned int *)(ack+2) = crc32(ack,2); //在原始帧的基础上加检验和 } //主函数 int main(int argc, char **argv) { int event, arg, n , m , i , j , len = 0 ,in_len = 0; unsigned char my_buf[260]; int phl_wait=0; //在物理层中还没有被发送的帧 protocol_init(argc, argv); enable_network_layer(); for (;;) { event = wait_for_event(&arg); switch (event) { case NETWORK_LAYER_READY:
C语言实现Ackermann函数的非递归算法,可以借助链栈来实现。具体步骤如下: 1. 定义一个链栈结构体,包含栈顶指针和栈的最大容量。定义一个函数来初始化栈。 2. 定义一个函数来判断栈是否为空。 3. 定义一个函数来判断栈是否已满。 4. 定义一个函数来在栈顶插入一个元素。 5. 定义一个函数来从栈顶删除一个元素并返回其值。 6. 定义一个函数来获取栈顶元素的值。 7. 定义一个函数来计算Ackermann函数的值,其中借助链栈来实现非递归算法。 下面是C语言代码实现: ```c #include <stdio.h> #include <stdlib.h> #define STACK_SIZE 1000 // 链栈结构体 typedef struct { int top; int arr[STACK_SIZE]; } Stack; // 初始化链栈 void init_stack(Stack* stack) { stack->top = -1; } // 判断栈是否为空 int is_empty(Stack* stack) { return stack->top == -1; } // 判断栈是否已满 int is_full(Stack* stack) { return stack->top == STACK_SIZE - 1; } // 在栈顶插入一个元素 void push(Stack* stack, int value) { if (is_full(stack)) { printf("Stack overflow!\n"); exit(EXIT_FAILURE); } stack->arr[++stack->top] = value; } // 从栈顶删除一个元素并返回其值 int pop(Stack* stack) { if (is_empty(stack)) { printf("Stack underflow!\n"); exit(EXIT_FAILURE); } return stack->arr[stack->top--]; } // 获取栈顶元素的值 int peek(Stack* stack) { if (is_empty(stack)) { printf("Stack is empty!\n"); exit(EXIT_FAILURE); } return stack->arr[stack->top]; } // 计算Ackermann函数的值 int ackermann(int m, int n) { Stack stack; init_stack(&stack); push(&stack, m); push(&stack, n); while (!is_empty(&stack)) { n = pop(&stack); m = pop(&stack); if (m == 0) { push(&stack, n + 1); } else if (m > 0 && n == 0) { push(&stack, m - 1); push(&stack, 1); } else if (m > 0 && n > 0) { push(&stack, m - 1); push(&stack, m); push(&stack, n - 1); } if (is_empty(&stack)) { return n; } } } int main() { int m = 3, n = 4; int result = ackermann(m, n); printf("Ackermann(%d, %d) = %d\n", m, n, result); return 0; } ``` 这个算法的时间复杂度是指数级别的,因此只能用于计算较小的Ackermann数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值