华清远见嵌入式学习——网络编程——作业3

目录

作业要求:基于UDP的TFTP文件传输

代码

下载功能效果图​编辑

上传功能效果图

思维导图

模拟面试题和答案(定期更新)


作业要求:基于UDP的TFTP文件传输

完成文件的上传和下载功能

代码

#include

//实现下载功能
int do_download(int cfd, struct sockaddr_in sin)
{
	//定义变量存储下载请求包
	char buf[516] = "";
	//定义变量存储文件名
	char fileName[40] = "";

	printf("请输入文件名:");
	scanf("%s", fileName);
	getchar();

	//组装请求包
	short *p1 = (short *)buf;
	*p1 = htons(1);                 //写1表明要下载

	char *p2 = buf+2;           //文件名段
	strcpy(p2, fileName);

	char *p3 = p2+strlen(p2)+1;    //模式段
	strcpy(p3, "octet");

	int size = 4 + strlen(p2) + strlen(p3);      //要发送的请求包的大小

	//向服务器发送下载请求
	if(sendto(cfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
	{
		perror("sendto error");
		return -1;
	}

	printf("请求成功\n");

	socklen_t socklen = sizeof(sin);
 
	//打开一文件接受下载文件
	int fd = open(fileName,O_RDWR|O_TRUNC|O_CREAT,0666);
	if(fd<0)
	{
		perror("open error");
		return -1;
	}
	int  res;
	while(1){
		//接受数据包
		bzero(buf,sizeof(buf));
		res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
		if(res<0)
		{
			perror("recvfrom error");
			return -1;
		}
 
		if(buf[1]==3)
		{
			//写入文件
			if(write(fd,buf+4,res-4)<0)
			{
				perror("write");
				return -1;
			}
 
			//构造ACK
			buf[1] = 4;
			//发送ACK
			if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))<0)
			{
				perror("sendto");
				return -1;
			}
 
			//判断数据包中的数据大小
			if(res-4<512)
			{
				printf("%s 下载完毕\n",fileName);
				break;
			}
		}else if(buf[1]==5)
		{
			printf("%d %s\n",ntohs(*(short*)(buf+2)),buf+4);
			break;
		}
	}
	close(fd);	
	return 0;
}

//实现上传功能
int do_upload(int cfd,struct sockaddr_in sin)
{
	//定义变量存储上传请求包
	char buf[516] = "";
	//定义变量存储文件名
	char fileName[40] = "";

	printf("请输入文件名:");
	scanf("%s", fileName);
	getchar();

	//组装请求包
	short *p1 = (short *)buf;
	*p1 = htons(2);                 //写2表明要上传

	char *p2 = buf+2;           //文件名段
	strcpy(p2, fileName);

	char *p3 = p2+strlen(p2)+1;    //模式段
	strcpy(p3, "octet");

	int size = 4 + strlen(p2) + strlen(p3);      //要发送的请求包的大小

	//向服务器发送上传请求
	if(sendto(cfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
	{
		perror("sendto error");
		return -1;
	}

	printf("请求成功\n");

	socklen_t socklen = sizeof(sin);
 
	//打开准备上传的文件
	int fd = open(fileName,O_RDONLY);
	if(fd<0)
	{
		perror("open error");
		return -1;
	}
	int res1,res2;
	int kbh = 1;
	while(1)
	{
		//接受数据包
		bzero(buf,sizeof(buf));
		res1 = recvfrom(cfd,buf,4,0,(struct sockaddr*)&sin,&socklen);
		if(res1 < 0)
		{
			perror("recvfrom error");
			return -1;
		}
 
		//判断是否接收到服务器发来的ACK
		if(buf[1]==4)
		{
			//填充发送的数据包
			buf[1] = 3;
			buf[3] = kbh;
			
			res2 = read(fd,buf+4,512);
			if(res2 < 0)
			{
				perror("read error");
				return -1;
			}					

			//向服务器发送数据包
			if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) == -1)
			{
				perror("sendto error");
				return -1;
			}
	
			//发一次块编号加一一次
			kbh++;
			
			//循环退出条件
			if(res2 < 512)
			{
				close(fd);
				printf("文件上传完毕\n");
				break;
			}
		}else if(buf[1]==5)
		{
			printf("%d %s\n",ntohs(*(short*)(buf+2)),buf+4);
			break;
		}
	}
	return 0;
}
int main(int argc, const char *argv[])
{
	if(argc != 2)
	{
		printf("input error\n");
		printf("usage:./a.out ip\n");
		return -1;
	}

	//1、创建套接字
	int cfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(cfd == -1)
	{
		perror("socket error");
		return -1;
	}

	//2、填充服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(69);
	sin.sin_addr.s_addr = inet_addr(argv[1]);

	int menu = -1;
	while(1)
	{
		system("clear");                     //清屏
		printf("\t\t======1、下载=======\n");
		printf("\t\t======2、上传=======\n");
		printf("\t\t======0、退出=======\n");

		printf("请输入功能:");
		scanf("%d", &menu);
		getchar();

		//多分支选择
		switch(menu)
		{
			case 1:
				{
					do_download(cfd, sin);
				}
				break;

			case 2:
				{
					do_upload(cfd,sin);
				}
				break;
			case 0:
				goto POS;
			default:printf("输入功能有误,请重新输入\n");
		}

		//阻塞
		printf("输入任意键,按回车清空:");
		while(getchar() != '\n');
	}

POS:
	//关闭套接字
	close(cfd);


	return 0;
}

下载功能效果图华清远见嵌入式学习——网络编程——作业3_第1张图片

华清远见嵌入式学习——网络编程——作业3_第2张图片

华清远见嵌入式学习——网络编程——作业3_第3张图片

上传功能效果图

华清远见嵌入式学习——网络编程——作业3_第4张图片

华清远见嵌入式学习——网络编程——作业3_第5张图片

华清远见嵌入式学习——网络编程——作业3_第6张图片

思维导图

(从第二章到第五章)

模拟面试题和答案(定期更新)

华清远见嵌入式学习——网络编程——作业3_第7张图片

你可能感兴趣的:(学习,网络,c#)