哈工大计网实验二

SR_client,需要在目录下创建一个test的txt文本。

#include <stdlib.h>
#include <time.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <fstream>
#pragma comment(lib,"ws2_32.lib")
#define SERVER_PORT 12340 // 接收数据的端口号
#define SERVER_IP "127.0.0.1" // 服务器的 IP 地址
#define BUFFER_SIZE 1024 // 缓冲区大小
#define SEQ_SIZE 16 // 序列号个数
#define SWIN_SIZE 8 // 发送窗口大小
#define RWIN_SIZE 8 // 接收窗口大小
#define LOSS_RATE 0.8 // 丢包率0.2=1-0.8
using namespace std;

//代码基本结构与服务器端一致,不在本份代码中做过多注释


char cmdBuffer[50];
char buffer[BUFFER_SIZE];
char cmd[10];
char fileName[40];
char filePath[50];
char file[1024 * 1024];
int len = sizeof(SOCKADDR);
int recvSize;
int Deliver(char* file, int ack);
int Send(ifstream& infile, int seq, SOCKET socket, SOCKADDR* addr);
int MoveSendWindow(int seq);
int Read(ifstream& infile, char* buffer);
struct Cache {
	bool used;
	char buffer[BUFFER_SIZE];
	Cache() {
		used = false;
		ZeroMemory(buffer, sizeof(buffer));
	}
}recvWindow[SEQ_SIZE];
struct DataFrame {
	clock_t start;
	char buffer[BUFFER_SIZE];
	DataFrame() {
		start = 0;
		ZeroMemory(buffer, sizeof(buffer));
	}
}sendWindow[SEQ_SIZE];
int main(int argc, char* argv[]) {
	// 加载套接字库
	WORD wVersionRequested;
	WSADATA wsaData;
	// 版本 2.2
	wVersionRequested = MAKEWORD(2, 2);
	int err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		printf("Winsock.dll 加载失败,错误码: %d\n", err);
		return -1;
	}
	if (LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
		printf("找不到 %d.%d 版本的 Winsock.dll\n", LOBYTE(wVersionRequested), HIBYTE(wVersionRequested));
		WSACleanup();
		return -1;
	}
	else {
		printf("Winsock %d.%d 加载成功\n", LOBYTE(wVersionRequested), HIBYTE(wVersionRequested));
	}
	// 创建客户端套接字
	SOCKET socketClient = socket(AF_INET, SOCK_DGRAM, 0);
	// 设置为非阻塞模式
	int iMode = 1;
	ioctlsocket(socketClient, FIONBIO, (u_long FAR*) & iMode);
	SOCKADDR_IN addrServer;
	inet_pton(AF_INET, SERVER_IP, &addrServer.sin_addr);
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(SERVER_PORT);
	srand((unsigned)time(NULL));
	int status = 0;
	clock_t start;
	clock_t now;
	int seq;
	int ack;
	while (true) {
		gets_s(cmdBuffer, 50);
		sscanf_s(cmdBuffer, "%s%s", cmd, sizeof(cmd) - 1, fileName, sizeof(fileName) - 1);
		if (!strcmp(cmd, "upload")) {
			printf("申请上传文件: %s\n", fileName);
			strcpy_s(filePath, "./");
			strcat_s(filePath, fileName);
			ifstream infile(filePath);
			ack = 1;
			start = clock();
			seq = 0;
			status = 0;
			sendWindow[0].buffer[0] = 10;
			strcpy_s(sendWindow[0].buffer + 1, strlen(cmdBuffer) + 1, cmdBuffer);
			sendWindow[0].start = start - 1000L;
			while (true) {
				recvSize = recvfrom(socketClient, buffer, BUFFER_SIZE, 0, (SOCKADDR*)&addrServer, &len);
				switch (status)
				{
				case 0:
					if (recvSize > 0 && buffer[0] == 100) {
						if (!strcmp(buffer + 1, "OK")) {
							printf("申请通过, 开始上传...\n");
							start = clock();
							status = 1;
							sendWindow[0].start = 0L;
							continue;
						}
						else if (!strcmp(buffer + 1, "NO")) {
							status = -1;
							break;
						}
					}
					now = clock();
					if (now - sendWindow[0].start >= 1000L) {
						sendWindow[0].start = now;
						sendto(socketClient, sendWindow[0].buffer, strlen(sendWindow[0].buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
					}
					break;
				case 1:
					if ((float)rand() / RAND_MAX > LOSS_RATE && buffer[0] == 101 && recvSize > 0) {
						ack = buffer[1];
						ack--;
						recvSize = 0;
						buffer[0] = 0;
						printf(" ack = %d丢失, 当前起始 seq = %d\n", ack + 1, seq + 1);
						break;
					}
					if (recvSize > 0 && buffer[0] == 101) {
						start = clock();
						ack = buffer[1];
						ack--;
						sendWindow[ack].start = -1L;
						if (ack == seq) {
							seq = MoveSendWindow(seq);
						}
						printf("接收 ack = %d, 当前起始 seq = %d\n", ack + 1, seq + 1);
					}
					if (!Send(infile, seq, socketClient, (SOCKADDR*)&addrServer)) {
						printf("上传完毕...\n");
						status = 2;
						start = clock();
						sendWindow[0].buffer[0] = 10;
						strcpy_s(sendWindow[0].buffer + 1, 7, "Finish");
						sendWindow[0].start = start - 1000L;
						continue;
					}
					break;
				case 2:
					if (recvSize > 0 && buffer[0] == 100) {
						if (!strcmp(buffer + 1, "OK")) {
							buffer[0] = 10;
							strcpy_s(buffer + 1, 3, "OK");
							sendto(socketClient, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
							status = 3;
							break;
						}
					}
					now = clock();
					if (now - sendWindow[0].start >= 1000L) {
						sendWindow[0].start = now;
						sendto(socketClient, sendWindow[0].buffer, strlen(sendWindow[0].buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
					}
				default:
					break;
				}
				if (status == -1) {
					printf("服务器拒绝请求\n");
					infile.close();
					break;
				}
				if (status == 3) {
					printf("上传成功,结束通信\n");
					infile.close();
					break;
				}
				if (clock() - start >= 5000L) {
					printf("通信超时,结束通信\n");
					infile.close();
					break;
				}
				if (recvSize <= 0) {
					Sleep(200);
				}
			}
		}
		else if (!strcmp(cmd, "download")) {
			printf("申请下载文件 %s\n", fileName);
			strcpy_s(filePath, "./");
			strcat_s(filePath, fileName);
			ofstream outfile(filePath);
			start = clock();
			ack = 1;
			ack = 0;
			status = 0;
			sendWindow[0].buffer[0] = 10;
			strcpy_s(sendWindow[0].buffer + 1, strlen(cmdBuffer) + 1, cmdBuffer);
			sendWindow[0].start = start - 1000L;
			while (true) {
				recvSize = recvfrom(socketClient, buffer, BUFFER_SIZE, 0, (SOCKADDR*)&addrServer, &len);
				switch (status)
				{
				case 0:
					if (recvSize > 0 && buffer[0] == 100) {
						if (!strcmp(buffer + 1, "OK")) {
							printf("申请通过, 准备下载...\n");
							start = clock();
							status = 1;
							sendWindow[0].buffer[0] = 10;
							strcpy_s(sendWindow[0].buffer + 1, 3, "OK");
							sendWindow[0].start = start - 1000L;
							continue;
						}
						else if (!strcmp(buffer + 1, "NO")) {
							status = -1;
							break;
						}
					}
					now = clock();
					if (now - sendWindow[0].start >= 1000L) {
						sendWindow[0].start = now;
						sendto(socketClient, sendWindow[0].buffer, strlen(sendWindow[0].buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
					}
					break;
				case 1:
					if (recvSize > 0 && (unsigned char)buffer[0] == 200) {
						printf("开始下载...\n");
						start = clock();
						seq = buffer[1];
						printf("接收数据帧 seq = %d, data = %s, 发送ack = %d,起始 ack = %d\n", seq, buffer + 2, seq, seq + 1);
						seq--;
						recvWindow[seq].used = true;
						strcpy_s(recvWindow[seq].buffer, strlen(buffer + 2) + 1, buffer + 2);
						if (ack == seq) {
							ack = Deliver(file, ack);
						}
						status = 2;
						buffer[0] = 11;
						buffer[1] = seq + 1;
						buffer[2] = 0;
						sendto(socketClient, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
						continue;
					}
					now = clock();
					if (now - sendWindow[0].start >= 1000L) {
						sendWindow[0].start = now;
						sendto(socketClient, sendWindow[0].buffer, strlen(sendWindow[0].buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
					}
					break;
				case 2:
					if ((float)rand() / RAND_MAX > LOSS_RATE && recvSize > 0 && (unsigned char)buffer[0] == 200) {
						recvSize = 0;
						buffer[0] = 0;
						seq = buffer[1];
						int temp = seq - 1 - ack;
						if (temp < 0) {
							temp += SEQ_SIZE;
						}
						start = clock();
						seq--;
						if (temp < RWIN_SIZE) {
							if (!recvWindow[seq].used) {
								recvWindow[seq].used = true;
								strcpy_s(recvWindow[seq].buffer, strlen(buffer + 2) + 1, buffer + 2);
							}
						}
						printf("接收数据帧 seq = %d失败, 起始 ack = %d\n", seq + 1, ack + 1);
						buffer[0] = 11;
						buffer[1] = seq + 1;
						buffer[2] = 0;
						break;
					}
					if (recvSize > 0) {
						if ((unsigned char)buffer[0] == 200) {
							seq = buffer[1];
							int temp = seq - 1 - ack;
							if (temp < 0) {
								temp += SEQ_SIZE;
							}
							start = clock();
							seq--;
							if (temp < RWIN_SIZE) {
								if (!recvWindow[seq].used) {
									recvWindow[seq].used = true;
									strcpy_s(recvWindow[seq].buffer, strlen(buffer + 2) + 1, buffer + 2);
								}
								if (ack == seq) {
									ack = Deliver(file, ack);
								}
							}
							printf("接收数据帧 seq = %d, data = %s, 发送 ack = %d, 起始 ack = %d\n", seq + 1, buffer + 2, seq + 1, ack + 1);
							buffer[0] = 11;
							buffer[1] = seq + 1;
							buffer[2] = 0;
							sendto(socketClient, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
						}
						else if (buffer[0] == 100 && !strcmp(buffer + 1, "Finish")) {
							status = 3;
							outfile.write(file, strlen(file));
							buffer[0] = 10;
							strcpy_s(buffer + 1, 3, "OK");
							sendto(socketClient, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
							continue;
						}
					}
					break;
				default:
					break;
				}
				if (status == -1) {
					printf("服务器拒绝请求\n");
					outfile.close();
					break;
				}
				if (status == 3) {
					printf("下载成功, 结束通信\n");
					outfile.close();
					break;
				}
				if (clock() - start >= 5000L) {
					printf("通信超时, 结束通信\n");
					outfile.close();
					break;
				}
				if (recvSize <= 0) {
					Sleep(20);
				}
			}
		}
		else if (!strcmp(cmd, "quit")) {
			break;
		}
	}
	closesocket(socketClient);
	printf("关闭套接字\n");
	WSACleanup();
	return 0;
}

int Read(ifstream& infile, char* buffer) {
	if (infile.eof()) {
		return 0;
	}
	infile.read(buffer, 3);
	int cnt = infile.gcount();
	buffer[cnt] = 0;
	return cnt;
}

int Deliver(char* file, int ack) {
	while (recvWindow[ack].used) {
		recvWindow[ack].used = false;
		strcat_s(file, strlen(file) + strlen(recvWindow[ack].buffer) + 1, recvWindow[ack].buffer);
		ack++;
		ack %= SEQ_SIZE;
	}
	return ack;
}

int Send(ifstream& infile, int seq, SOCKET socket, SOCKADDR* addr) {
	clock_t now = clock();
	for (int i = 0; i < SWIN_SIZE; i++) {
		int j = (seq + i) % SEQ_SIZE;
		if (sendWindow[j].start == -1L) {
			continue;
		}
		if (sendWindow[j].start == 0L) {
			if (Read(infile, sendWindow[j].buffer + 2)) {
				sendWindow[j].start = now;
				sendWindow[j].buffer[0] = 20;
				sendWindow[j].buffer[1] = j + 1;
			}
			else if (i == 0) {
				return 0;
			}
			else {
				break;
			}
		}
		else if (now - sendWindow[j].start >= 1000L) {
			sendWindow[j].start = now;
		}
		else {
			continue;
		}
		printf("发送数据帧 seq = %d, data = %s\n", j + 1, sendWindow[j].buffer + 2);
		sendto(socket, sendWindow[j].buffer, strlen(sendWindow[j].buffer) + 1, 0, addr, sizeof(SOCKADDR));
	}
	return 1;
}

int MoveSendWindow(int seq) {
	while (sendWindow[seq].start == -1L) {
		sendWindow[seq].start = 0L;
		seq++;
		seq %= SEQ_SIZE;
	}
	return seq;
}

SR_server,在目录下创建一个test1的txt文本

#include <stdlib.h>
#include <time.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <fstream>
#pragma comment(lib,"ws2_32.lib")
#define SERVER_PORT 12340 // 端口号
#define SERVER_IP "0.0.0.0" // IP 地址
#define SEQ_SIZE 16 // 序列号个数
#define SWIN_SIZE 8 // 发送窗口大小
#define RWIN_SIZE 8 // 接收窗口大小
#define BUFFER_SIZE 1024 // 缓冲区大小
#define LOSS_RATE 0.8 //丢包率0.2=1-0.8
using namespace std;
struct recv {
	bool used;
	char buffer[BUFFER_SIZE];
	recv() {
		used = false;
		ZeroMemory(buffer, sizeof(buffer));
	}
}recvWindow[SEQ_SIZE];
struct send {
	clock_t start;//由于使用的是SR,因此每一个窗口位置都需要设置一个计时器
	char buffer[BUFFER_SIZE];
	send() {
		start = 0;
		ZeroMemory(buffer, sizeof(buffer));
	}
}sendWindow[SEQ_SIZE];
char cmdBuffer[50];
char buffer[BUFFER_SIZE];
char cmd[10];
char fileName[40];
char filePath[50];
char file[1024 * 1024];
int len = sizeof(SOCKADDR);
int recvSize;
int Deliver(char* file, int ack);
int Send(ifstream& infile, int seq, SOCKET socket, SOCKADDR* addr);
int MoveSendWindow(int seq);
int Read(ifstream& infile, char* buffer);
//主函数
int main(int argc, char* argv[]) {
	// 加载套接字库
	WORD wVersionRequested;
	WSADATA wsaData;
	// 版本 2.2
	wVersionRequested = MAKEWORD(2, 2);
	int err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0) {
		printf("Winsock.dll 加载失败,错误码: %d\n", err);
		return -1;
	}
	if (LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
		printf("找不到 %d.%d 版本的 Winsock.dll\n", LOBYTE(wVersionRequested), HIBYTE(wVersionRequested));
		WSACleanup();
		return -1;
	}
	else {
		printf("Winsock %d.%d 加载成功\n", LOBYTE(wVersionRequested), HIBYTE(wVersionRequested));
	}
	// 创建服务器套接字
	SOCKET socketServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	// 设置为非阻塞模式
	int iMode = 1;
	ioctlsocket(socketServer, FIONBIO, (u_long FAR*) & iMode);
	SOCKADDR_IN addrServer;
	inet_pton(AF_INET, SERVER_IP, &addrServer.sin_addr);
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(SERVER_PORT);
	// 绑定端口
	if (err = bind(socketServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR))) {
		err = GetLastError();
		printf("绑定端口 %d 失败,错误码: % d\n", SERVER_PORT, err);
		WSACleanup();
		return -1;
	}
	else {
		printf("绑定端口 %d 成功", SERVER_PORT);
	}
	SOCKADDR_IN addrClient;
	int status = 0;
	clock_t start;
	clock_t now;
	int seq;
	int ack;
	ofstream outfile;
	ifstream infile;
	//进入接收状态,注意服务器主要处理的任务是接收客户机请求,共有上载和下载两种任务
	while (true) {
		recvSize = recvfrom(socketServer, buffer, BUFFER_SIZE, 0, ((SOCKADDR*)&addrClient), &len);
		switch (status)
		{
		case 0://接收请求
			if (recvSize > 0 && buffer[0] == 10) {
				char addr[100];
				ZeroMemory(addr, sizeof(addr));
				inet_ntop(AF_INET, &addrClient.sin_addr, addr, sizeof(addr));
				sscanf_s(buffer + 1, "%s%s", cmd, sizeof(cmd) - 1, fileName, sizeof(fileName) - 1);
				if (strcmp(cmd, "upload") && strcmp(cmd, "download")) {
					continue;
				}
				strcpy_s(filePath, "./");
				strcat_s(filePath, fileName);
				printf("收到来自客户端 %s 的请求: %s\n", addr, buffer);
				printf("是否同意该请求(Y/N)?");
				gets_s(cmdBuffer, 50);
				if (!strcmp(cmdBuffer, "Y")) {
					buffer[0] = 100;
					strcpy_s(buffer + 1, 3, "OK");
					if (!strcmp(cmd, "upload")) {
						file[0] = 0;
						start = clock();
						ack = 0;
						status = 1;
						outfile.open(filePath);
					}
					else if (!strcmp(cmd, "download")) {
						start = clock();
						seq = 0;
						status = -1;
						infile.open(filePath);
					}
				}
				else {
					buffer[0] = 100;
					strcpy_s(buffer + 1, 3, "NO");
				}
				sendto(socketServer, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrClient, sizeof(SOCKADDR));
			}
			break;
		case 1://客户机请求上传,也就是服务器端是接收方
			if ((float)rand() / RAND_MAX > LOSS_RATE && recvSize > 0 && buffer[0] == 20) {
				seq = buffer[1];
				int temp = seq - 1 - ack;
				if (temp < 0) {
					temp += SEQ_SIZE;
				}
				seq--;
				if (temp < RWIN_SIZE) {
					if (!recvWindow[seq].used) {
						recvWindow[seq].used = true;
						strcpy_s(recvWindow[seq].buffer, strlen(buffer + 2) + 1, buffer + 2);
					}
				}
				recvSize = 0;
				buffer[0] = 0;
				printf("数据帧 seq = %d丢失, 起始 ack = %d\n", seq + 1, ack + 1);
				buffer[0] = 101;
				buffer[1] = seq + 1;
				buffer[2] = 0;
				break;
			}
			if (recvSize > 0) {
				if (buffer[0] == 20) {
					seq = buffer[1];
					int temp = seq - 1 - ack;
					if (temp < 0) {
						temp += SEQ_SIZE;
					}
					start = clock();
					seq--;
					if (temp < RWIN_SIZE) {
						if (!recvWindow[seq].used) {
							recvWindow[seq].used = true;
							strcpy_s(recvWindow[seq].buffer, strlen(buffer + 2) + 1, buffer + 2);
						}
						if (ack == seq) {
							ack = Deliver(file, ack);
						}
					}
					printf("接收数据帧 seq = %d, data = %s, 发送 ack = %d, 起始 ack = %d\n", seq + 1, buffer + 2, seq + 1, ack + 1);
					buffer[0] = 101;
					buffer[1] = seq + 1;
					buffer[2] = 0;
					sendto(socketServer, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrClient, sizeof(SOCKADDR));
				}
				else if (buffer[0] == 10) {
					if (!strcmp(buffer + 1, "Finish")) {
						printf("传输完毕...\n");
						start = clock();
						sendWindow[0].start = start - 1000L;
						sendWindow[0].buffer[0] = 100;
						strcpy_s(sendWindow[0].buffer + 1, 3, "OK");
						outfile.write(file, strlen(file));
						status = 2;
					}
					buffer[0] = 100;
					strcpy_s(buffer + 1, 3, "OK");
					sendto(socketServer, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrClient, sizeof(SOCKADDR));
				}
			}
			break;
		case 2://接收完成
			if (recvSize > 0 && buffer[0] == 10 && !strcmp(buffer + 1, "OK")) {
				printf("传输成功,结束通信\n");
				status = 0;
				outfile.close();
			}
			now = clock();
			if (now - sendWindow[0].start >= 1000L) {
				sendWindow[0].start = now;
				sendto(socketServer, sendWindow[0].buffer, strlen(sendWindow[0].buffer) + 1, 0, (SOCKADDR*)&addrClient, sizeof(SOCKADDR));
			}
			break;
		case -1://客户机请求下载,也就是服务器端充当发送方
			if (recvSize > 0) {
				if (buffer[0] == 10) {
					if (!strcmp(buffer + 1, "OK")) {
						printf("开始传输...\n");
						start = clock();
						status = -2;
					}
					buffer[0] = 100;
					strcpy_s(buffer + 1, 3, "OK");
					sendto(socketServer, buffer, strlen(buffer) + 1, 0, (SOCKADDR*)&addrClient, sizeof(SOCKADDR));
				}
			}
			break;
		case -2://服务器端发送数据
			if ((float)rand() / RAND_MAX > LOSS_RATE && recvSize > 0 && buffer[0] == 11) {
				ack = buffer[1];
				ack--;
				recvSize = 0;
				buffer[0] = 0;
				printf(" ack = %d丢失, 当前起始 seq = %d\n", ack + 1, seq + 1);
				break;
			}
			if (recvSize > 0 && buffer[0] == 11) {
				start = clock();
				ack = buffer[1];
				ack--;
				sendWindow[ack].start = -1L;
				if (ack == seq) {
					seq = MoveSendWindow(seq);
				}
				printf("接收 ack = %d, 当前起始 seq = %d\n", ack + 1, seq + 1);
			}
			if (!Send(infile, seq, socketServer, (SOCKADDR*)&addrClient)) {
				printf("传输完毕...\n");
				status = -3;
				start = clock();
				sendWindow[0].buffer[0] = 100;
				strcpy_s(sendWindow[0].buffer + 1, 7, "Finish");
				sendWindow[0].start = start - 1000L;
			}
			break;
		case -3://请求完成
			if (recvSize > 0 && buffer[0] == 10) {
				if (!strcmp(buffer + 1, "OK")) {
					printf("传输成功,结束通信\n");
					infile.close();
					status = 0;
					break;
				}
			}
			now = clock();
			if (now - sendWindow[0].start >= 1000L) {
				sendWindow[0].start = now;
				sendto(socketServer, sendWindow[0].buffer, strlen(sendWindow[0].buffer) + 1, 0, (SOCKADDR*)&addrClient, sizeof(SOCKADDR));
			}
		default:
			break;
		}
		if (status != 0 && clock() - start > 5000L) {
			printf("通信超时, 结束通信\n");
			status = 0;
			outfile.close();
			continue;
		}
		if (recvSize <= 0) {
			Sleep(20);
		}
	}
	//关闭套接字,卸载库
	closesocket(socketServer);
	WSACleanup();
	return 0;
}
int Read(ifstream& infile, char* buffer) {
	//从文件中读取需要发送的数据
	if (infile.eof()) {
		return 0;
	}
	infile.read(buffer, 3);
	int cnt = infile.gcount();
	buffer[cnt] = 0;
	return cnt;
}
int Deliver(char* file, int ack) {
	while (recvWindow[ack].used) {
		recvWindow[ack].used = false;
		strcat_s(file, strlen(file) + strlen(recvWindow[ack].buffer) + 1, recvWindow[ack].buffer);
		ack++;
		ack %= SEQ_SIZE;
	}
	return ack;
}
int Send(ifstream& infile, int seq, SOCKET socket, SOCKADDR* addr) {
	//发送数据
	clock_t now = clock();
	for (int i = 0; i < SWIN_SIZE; i++) {
		int j = (seq + i) % SEQ_SIZE;
		if (sendWindow[j].start == -1L) {//传输超时,不需要
			continue;
		}
		if (sendWindow[j].start == 0L) {//开始计时
			if (Read(infile, sendWindow[j].buffer + 2)) {
				sendWindow[j].start = now;
				sendWindow[j].buffer[0] = 200;
				sendWindow[j].buffer[1] = j + 1;
			}
			else if (i == 0) {
				return 0;
			}
			else {
				break;
			}
		}
		else if (now - sendWindow[j].start >= 1000L) {//更新时间
			sendWindow[j].start = now;
		}
		else {
			continue;
		}
		printf("发送数据帧 seq = %d, data = %s\n", j + 1, sendWindow[j].buffer + 2);
		sendto(socket, sendWindow[j].buffer, strlen(sendWindow[j].buffer) + 1, 0, addr, sizeof(SOCKADDR));
	}
	return 1;
}

int MoveSendWindow(int seq) {
	//移动窗口
	while (sendWindow[seq].start == -1L) {
		sendWindow[seq].start = 0L;
		seq++;
		seq %= SEQ_SIZE;
	}
	return seq;
}

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值