网络编程day4

网络编程day4

码农世界 2024-05-22 后端 60 次浏览 0个评论

 tftp代码实现

#define SER_PORT 69
#define SER_IP "192.168.125.85"
int sockfd;
char buf[516];
struct sockaddr_in ser_sockaddr;
void print_menu();
void upload(const char* filename);
void download(const char* filename);
int main(int argc, const char *argv[])
{
	char num;  // 菜单选择号
	char filename[30];
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd == -1) {
		perror("socket");
		return -1;
	}
	ser_sockaddr.sin_family = AF_INET;
	ser_sockaddr.sin_port = htons(SER_PORT);
	ser_sockaddr.sin_addr.s_addr = inet_addr(SER_IP);
	print_menu();
	while (1) {
		printf("请选择->");
		scanf(" %c", &num);
		switch (num) {
		case '1':
			printf("请输入上传文件名->");
			scanf("%s", filename);
			upload(filename);
			break;
		case '2':
			printf("请输入下载文件名->");
			scanf("%s", filename);
			download(filename);
			break;
		case '3':
			system("clear");
			print_menu();
			break;
		case '4':
			close(sockfd);
			return 0;
		default:
			puts("输入错误,请重新输入");
		}
	}
	return 0;
}
void print_menu() {
	puts("**************************************");
	puts("***************1 上传*****************");
	puts("***************2 下载*****************");
	puts("***************3 清屏*****************");
	puts("***************4 退出*****************");
	puts("**************************************");
}
void upload(const char* filename) {
	// 发送写请求
	short* op_ptr = (short*)buf;
	*op_ptr = htons(2);
	char* filename_ptr = buf + 2;
	strcpy(filename_ptr, filename);
	char* mode_ptr = filename_ptr + strlen(filename_ptr) + 1;
	strcpy(mode_ptr, "octet");
	int req_len = 4 + strlen(filename_ptr) + strlen(mode_ptr);
	sendto(sockfd, buf, req_len, 0, (struct sockaddr*)&ser_sockaddr, sizeof(struct sockaddr));
	socklen_t sockaddr_len = sizeof(struct sockaddr);
	recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&ser_sockaddr, &sockaddr_len);
	//收到操作码为5,代表上传发生错误
	if (ntohs(*(short*)buf) == 5) {
		printf("%s\n", buf + 4);
		return;
	}
	int i = 1;  // 块编号
	int rfd = open(filename, O_RDONLY);
	if (rfd == -1) {
		perror("open");
		return;
	}
	while (1) {
		*op_ptr = htons(3);
		short* blocknum_ptr = (short*)(buf + 2);
		*blocknum_ptr = htons(i++);
		int ret = read(rfd, buf + 4, 512);
		sendto(sockfd, buf, ret + 4, 0, (struct sockaddr*)&ser_sockaddr, sockaddr_len);
		// 等待服务器端ACK
		recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&ser_sockaddr, &sockaddr_len);
		if (ntohs(*(short*)buf) == 5) {
			printf("%s\n", buf + 4);
			close(rfd);
			return;
		}
		if (ret < 512) {
			puts("上传完成");
			close(rfd);
			return;
		}
	}
}
void download(const char* filename) {
	// 发送读请求
	short* op_ptr = (short*)buf;
	*op_ptr = htons(1);
	char* filename_ptr = buf + 2;
	strcpy(filename_ptr, filename);
	char* mode_ptr = filename_ptr + strlen(filename_ptr) + 1;
	strcpy(mode_ptr, "octet");
	int req_len = 4 + strlen(filename_ptr) + strlen(mode_ptr);
	sendto(sockfd, buf, req_len, 0, (struct sockaddr*)&ser_sockaddr, sizeof(struct sockaddr));
	int wfd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0666);
	if (wfd == -1) {
		perror("open");
		return;
	}
	int i = 1; 	//块编号
	socklen_t sockaddr_len = sizeof(struct sockaddr);
	while (1) {
		// 接收数据包
		int ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&ser_sockaddr, &sockaddr_len);
		if (ret < 0) {
			perror("recvfrom");
			close(wfd);
			return;
		}
		write(wfd, buf + 4, ret - 4);
		// 发送ACK
		*op_ptr = htons(4);
		short* blocknum_ptr = (short*)(buf + 2);
		*blocknum_ptr = htons(i++);
		sendto(sockfd, buf, 4, 0, (struct sockaddr*)&ser_sockaddr, sockaddr_len);
		if (ret < 516) {
			puts("下载完成");
			close(wfd);
			return;
		}
	}
}

网络编程day4

转载请注明来自码农世界,本文标题:《网络编程day4》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,60人围观)参与讨论

还没有评论,来说两句吧...

Top