9.16作业

TFTP练习

#include <stdio.h> 
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>

//定义辅助宏
#define ERR_MSG(msg)do{\
	fprintf(stderr,"__%d__:",__LINE__);\
	perror(msg);\
}while(0)

#define PROT 69
#define IP  "192.168.1.11"


int do_download(int sfd,struct sockaddr_in sin)
{
	char buf[516] = ""; //初始化字符串
	char filename[20]="";
	printf("请输入要下载的文件名:");
	scanf("%s",filename);

	//组下载请求包
	char* ptr = buf;
	unsigned short* ptr1 = (unsigned short*)ptr;
	*ptr1 = htons(1); //下载请求的网络字节序
	char* ptr2 = ptr+2;
	//char* ptr2 = ptr1+2;
	strcpy(ptr2, filename);
	char* ptr3 = ptr2+strlen(ptr2);
	*ptr3 = 0;
	char* ptr4 = ptr3+1;
	strcpy(ptr4, "octet");
	/*
	char *ptr5=ptr4+1;
	*ptr5=0;
	*/
	int size = 2+strlen(ptr2)+1+strlen(ptr4)+1;
	printf("%d\n",size);

	//发送下载请求包
	if(sendto(sfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("sendto");
		return -1;
	}
	printf("发送下载请求包成功\n");
	
	
	//打开一个文件
	//unsigned char str[600]="";
	socklen_t addrlen=sizeof(sin);
	unsigned short block_num = 0;  //块编号 或者 错误码

	int fd_w=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0777);

	while(1)
	{
		bzero(buf,sizeof(buf));
		//循环接收服务器返回的数据包
		ssize_t recv_len=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
		printf("size=%ld\n",recv_len);
		if( recv_len < 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		
		printf("buf[1]=%d\n",buf[1]);
		
		//分析是数据包还是错误包
		//如果是数据包,则将数据提取出来,数据在buf+4的位置上
		//将提取出来的数据写入到文件中
		//组ACK包,回复ACK给服务器
		//直到数据内容的长度小于512个字节
		//如果是错误包,
		//则打印错误信息,退出

		if( 3 == buf[1])
		{
			printf("此包为数据包\n");
		
			//判断块编号
			if(block_num == ntohs(*(unsigned short*)(buf+2)))
			{
				write(fd_w,buf+4,size-4);
				//block_num++;
			}
				//发出应答包
				buf[1]=4;
				if(sendto(sfd, buf, 4, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
				{
					ERR_MSG("sendto");
					return -1;
				}

				//判断包的大小
				if(size <516 )
				{
					printf("下载完毕\n");
					break;
				}
		}

		else if( 5 == buf[1])
		{
			printf("此包为错误包\n");
			break;
		}
	}
	return 0;
}

int do_upload(int sfd,struct sockaddr_in sin)
{
	char buf[516] = ""; //初始化字符串
	char filename[20]= "";
	printf("请输入上传的文件名:");
	scanf("%s",filename);
	//fgets(filename,20,stdin);
	getchar();
	//filename[strlen(filename)-1]=0;
	
	//判断文件是否存在
	int fd_r=open(filename,O_RDONLY);
	
	/*
	printf("%d\n",errno);
	printf("%d\n",ENOENT);
	*/

	if( fd_r <0)
	{
		if(errno == ENOENT)
		{
			printf(">>>文件不存在,请重新输入<<<\n");
			return -2;
		}
		else
		{
			ERR_MSG("open");
			return -2;
		}
	}

	//组上传请求包
	char* ptr = buf;
	unsigned short* ptr1 = (unsigned short*)ptr;
	*ptr1 = htons(2); //上传请求的网络字节序
	char* ptr2 = ptr+2;
	//char* ptr2 = ptr1+2;
	strcpy(ptr2, filename);
	char* ptr3 = ptr2+strlen(ptr2);
	*ptr3 = 0;
	char* ptr4 = ptr3+1;
	strcpy(ptr4, "octet");
	/*
	char *ptr5=ptr4+1;
	*ptr5=0;
	*/
	int size = 2+strlen(ptr2)+1+strlen(ptr4)+1;
	//printf("%d\n",size);

	//发送上传请求包
	if(sendto(sfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("sendto");
		return -1;
	}
	//printf("buf=%s\n",buf);
	
	printf("发送上传请求包成功\n");
	
	unsigned short block_num = 0;  //块编号 或者 错误码
	socklen_t addrlen=sizeof(sin);

	while(1)
	{
		//循环接收服务器返回的数据包
		bzero(buf,sizeof(buf));
		int ret =recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);
		printf("ret=%d\n",size);

		if( ret< 0)
		{
			ERR_MSG("recvfrom");
			return -1;
		}
		
		printf("%d\n",buf[1]);


		if( 4 == buf[1])
		{
			//判断块编号
			if(block_num == ntohs(*(unsigned short*)(buf+2)))
			{
				//修改操作码
				buf[1]=3;
			
				//填充块编号
				block_num++;
				*(unsigned short*)(buf+2) = htons(block_num);

				int res= read(fd_r,buf+4,sizeof(buf)-4);
				printf("res=%d\n",res);

				if(res <0 )
				{
					ERR_MSG("read");
					return -1;
				}
				
				else if( 0 == res)
				{
					printf("%s文件上传完毕\n",filename);
					break;
				}

				//block_num++;

				//发出数据
				if(sendto(sfd, buf, res+4, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
				{
					ERR_MSG("sendto");
					return -1;
				}
			}
			else
			{
				printf("文件上传失败\n");
				break;
			}

		}

		else if( 5 == buf[1])
		{
			printf("此包为错误包\n");
			break;
		}
	}
	return 0;
}

效果图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了将Postman 9.16.0汉化,您可以按照以下步骤进行操作: 1. 首先,您需要下载Postman的汉化包。您可以在GitHub上找到postman汉化包的下载链接,具体*** 下载汉化包后,您需要找到Postman安装的目录。通常情况下,Postman的安装目录位于C:\Users\[用户名]\AppData\Local\Postman。您可以打开资源管理器,在地址栏中输入该路径,找到Postman的安装目录。 3. 在Postman的安装目录中,找到一个名为"app.zip"的文件。您可以从引用提供的博客资源中下载此版本的app.zip。 4. 解压缩app.zip文件,并将解压后的文件夹中的内容复制到Postman安装目录下的"resources"文件夹中。覆盖原有的文件。 5. 关闭并重新启动Postman应用程序。现在,您应该可以看到Postman已经汉化成功了。 请注意,确保您下载的汉化包和Postman的版本号相匹配。如果您下载的汉化包与您的Postman版本不匹配,可能会导致一些兼容性问题。 希望这些步骤可以帮助您成功汉化Postman 9.16.0版本!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [postman汉化包下载](https://blog.csdn.net/qq_33212312/article/details/125014303)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [postman中文设置以及Test断言设置总结](https://blog.csdn.net/github_35856054/article/details/118051565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值