/* 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 */
计算机网络课程实验——可靠传输协议:(3)GBN(unidirectional)
最新推荐文章于 2024-07-22 18:36:20 发布
这是一个关于计算机网络课程实验的实现,专注于可靠传输协议的GBN(Go-Back-N)方法,用于单向数据传输。实验代码中包含了序列号、确认号的计算、错误检查以及数据包的发送和接收处理逻辑。
摘要由CSDN通过智能技术生成