计算机网络之GBN协议

本文深入探讨了GBN(Go-Back-N)协议在计算机网络中的应用,通过实例展示了客户端和服务器端程序的设计与实现,主要使用C++语言,并在VS2015环境下进行开发。内容涵盖GBN协议的基本原理、错误检测与纠正机制,以及实际编程中的关键点。
摘要由CSDN通过智能技术生成

客户端程序:

//#include "stdafx.h" //创建 VS 项目包含的预编译头文件
#include <stdlib.h>
#include <time.h>
#include <WinSock2.h>
#include <fstream>
#include<iostream>
#include<stdio.h>
#include <io.h> 
#pragma comment(lib,"ws2_32.lib")
#define SERVER_PORT  12340  //端口号
#define SERVER_IP  "0.0.0.0" //IP 地址
const int BUFFER_LENGTH = 1026; //缓冲区大小, (以太网中 UDP 的数据帧中包长度应小于 1480 字节)
const int SEND_WIND_SIZE = 10;//发送窗口大小为 10,GBN 中应满足 W + 1 <=N(W 为发送窗口大小,N 为序列号个数)
//本例取序列号 0...19 共 20 个
//如果将窗口大小设为 1,则为停-等协议
const int SEQ_SIZE = 20; //序列号的个数,从 0~19 共计 20 个
//由于发送数据第一个字节如果值为 0, 则数据会发送失败
//因此接收端序列号为 1~20,与发送端一一对应
BOOL ack[SEQ_SIZE];//收到 ack 情况,对应 0~19 的 ack
int curSeq;//当前数据包的 seq
int curAck;//当前等待确认的 ack
int totalSeq;//收到的包的总数
int totalPacket;//需要发送的包总数
int size;
int flag = 0; //标识是否收到最后一个ack
//************************************
// Method: getCurTime
// FullName: getCurTime
// Access: public
// Returns: void
// Qualifier: 获取当前系统时间,结果存入 ptime 中
// Parameter: char * ptime
//************************************
void getCurTime(char *ptime) {
	char buffer[128];
	memset(buffer, 0, sizeof(buffer));
	time_t c_time;
	struct tm *p;
	p = new tm;
	time(&c_time);
	localtime_s(p, &c_time);
	sprintf_s(buffer, "%d/%d/%d %d:%d:%d",
		p->tm_year + 1900,
		p->tm_mon,
		p->tm_mday,
		p->tm_hour,
		p->tm_min,
		p->tm_sec);
	strcpy_s(ptime, sizeof(buffer), buffer);
}
//************************************
// Method: seqIsAvailable
// FullName: seqIsAvailable
// Access: public
// Returns: bool
// Qualifier: 当前序列号 curSeq 是否可用
//************************************
bool seqIsAvailable() {
	int step;
	step = curSeq - curAck;
	step = step >= 0 ? step : step + SEQ_SIZE;
	//序列号是否在当前发送窗口之内
	if (step >= SEND_WIND_SIZE) {
		return false;
	}
	if (ack[curSeq]) {
		return true;
	}
	return false;
}
//************************************
// Method: timeoutHandler
// FullName: timeoutHandler
// Access: public
// Returns: void
// Qualifier: 超时重传处理函数,滑动窗口内的数据帧都要重传
//************************************
void timeoutHandler() {
	printf("Timer out error.\n");
	int index;
	for (int i = 0; i< SEND_WIND_SIZE; ++i) {
		index = (i + curAck) % SEQ_SIZE;
		ack[index] = TRUE;
	}
	totalSeq -= SEND_WIND_SIZE;
	curSeq = curAck;
}
//************************************
// Method: ackHandler
// FullName: ackHandler
// Access: public
// Returns: void
// Qualifier: 收到 ack,累积确认,取数据帧的第一个字节
//由于发送数据时,第一个字节(序列号)为 0(ASCII)时发送失败,因此加一了,此处需要减一还原
// Parameter: char c
//************************************
void ackHandler(char c) {
	unsigned char index = (unsigned char)c - 1; //序列号减一
	printf("Recv a ack of %d\n", index);
	if (index >= (size / 1024))
		flag = 1;
	if (curAck <= index) {
		for (int i = curAck; i <= index; ++i) {
			ack[i] = TRUE;
		}
		curAck = (index + 1) % SEQ_SIZE;
	}
	else {
		//ack 超过了最大值,回到了 curAck 的左边
		for (int i = curAck; i< SEQ_SIZE; 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值