计算机网络课程实验——可靠传输协议:(3)GBN(unidirectional)

这是一个关于计算机网络课程实验的实现,专注于可靠传输协议的GBN(Go-Back-N)方法,用于单向数据传输。实验代码中包含了序列号、确认号的计算、错误检查以及数据包的发送和接收处理逻辑。
摘要由CSDN通过智能技术生成
/* Zhang Jingtun(Ordinary Crazy) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <time.h>

/* ******************************************************************
 ALTERNATING BIT AND GO-BACK-N NETWORK EMULATOR: VERSION 1.1  J.F.Kurose

   This code should be used for PA2, unidirectional or bidirectional
   data transfer protocols (from A to B. Bidirectional transfer of data
   is for extra credit and is not required).  Network properties:
   - one way network delay averages five time units (longer if there
     are other messages in the channel for GBN), but can be larger
   - packets can be corrupted (either the header or the data portion)
     or lost, according to user-defined probabilities
   - packets will be delivered in the order in which they were sent
     (although some can be lost).
**********************************************************************/

#define BIDIRECTIONAL 0    /* change to 1 if you're doing extra credit */
                           /* and write a routine called B_output */

/* a "msg" is the data unit passed from layer 5 (teachers code) to layer  */
/* 4 (students' code).  It contains the data (characters) to be delivered */
/* to layer 5 via the students transport level protocol entities.         */
struct msg {
  char data[20];
};

/* a packet is the data unit passed from layer 4 (students code) to layer */
/* 3 (teachers code).  Note the pre-defined packet structure, which all   */
/* students must follow. */
struct pkt {
   int seqnum;
   int acknum;
   int checksum;
   char payload[20];
};

/********* STUDENTS WRITE THE NEXT SEVEN ROUTINES *********/

#define OK 1
#define ERROR 0
#define A_WINDOWSIZE 8
#define A_BUFFERSIZE 50
typedef int State;
typedef struct msg msg;
typedef struct pkt pkt;

void ComputeCheckSum(pkt* packet){
    packet->checksum = packet->seqnum + packet->acknum;
    int i;
    for(i = 0;i < 20;i += 4){
        int tmp1 = (int)packet->payload[i];
        int tmp2 = (int)packet->payload[i + 1];
        int tmp3 = (int)packet->payload[i + 2];
        int tmp4 = (int)packet->payload[i + 3];
        tmp2 *= 256;
        tmp3 *= 65536;
        tmp4 *= 16777216;
        packet->checksum += (tmp1 + tmp2 + tmp3 + tmp4);
     }
     packet->checksum = ~ packet->checksum;
}//ComputeCheckSum

int TestCheckSum(pkt* packet){
    int check = packet->checksum;
    check += (packet->seqnum + packet->acknum);
    int i;
    for(i = 0;i < 20;i += 4){
        int tmp1 = (int)packet->payload[i];
        int tmp2 = (int)packet->payload[i + 1];
        int tmp3 = (int)packet->payload[i + 2];
        int tmp4 = (int)packet->payload[i + 3];
        tmp2 *= 256;
        tmp3 *= 65536;
        tmp4 *= 16777216;
        check += (tmp1 + tmp2 + tmp3 + tmp4);
    }
    return check;
}//TestCheckSum

int A_base;         /* the first unacknowledged */
int A_nextseqnum;   
int A_seqnum;
int A_acknum;
int A_buffer_top;
float A_interval = 30.0;
pkt A_buffer[A_BUFFERSIZE];     /* packet buffer */
pkt B_packet;                   /* packet buffer */
int B_first_or_not;
int B_seqnum_looking_for;
int B_acknum;
char ACK[20] = "ACK";
char NAK[20] = "NAK";


/* called from layer 5, passed the data to be sent to other side */
State A_output(msg message){
    int i;
    if(((A_base + A_WINDOWSIZE) % A_BUFFERSIZE) == (A_nextseqnum)){
        if(((A_buffer_top) % A_BUFFERSIZE) == A_base){
            printf("BUFFER OVERFLOW!");
            return ERROR;
        }
        else{
            strncpy(A_buffer[A_buffer_top].payload,message.data,20);
            A_buffer_top = (A_buffer_top + 1) % A_BUFFERSIZE;
            return OK;
        }
    }
    else{
        strncpy(A_buffer[A_nextseqnum].payload,message.data,20);
        A_buffer[A_nextseqnum].seqnum = A_seqnum + (A_nextseqnum - A_base);
        A_buffer[A_nextseqnum].acknum = A_acknum + (A_nextseqnum - A_base);       
        ComputeCheckSum(&A_buffer[A_nextseqnum]);
        tolayer3(0,A_buffer[A_nextseqnum]);         /* tolayer3(calling_entity,packet) */
        if(A_nextseqnum == A_base) starttimer(0,A_interval);
                
        /* starttimer(calling_entity,increment) */
        
        /***********************************************************/
        printf("A: sending:\n");
        printf("   seq:%d, ack:%d,\n",A_buffer[A_nextseqnum].seqnum,A_buffer[A_nextseqnum].acknum);
        printf("   check:%X\n",A_buffer[A_nextseqnum].checksum);
        printf("   message: ");
        for(i = 0;i < 20;i ++) printf("%c",A_buffer[A_nextseqnum].payload[i]);
        printf("\n");
        /***********************************************************/
        A_nextseqnum = (A_nextseqnum + 1) % A_BUFFERSIZE;
        A_buffer_top = (A_buffer_top + 1) % A_BUFFERSIZE;
        
    }//if
    return OK;
}//A_output

State B_output(msg message){  /* need be completed only for extra credit */
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值