基于UDP的TFTP文件传输

代码:

#include <myhead.h>

//实现下载功能
int download(int cfd,struct sockaddr_in sin)
{
	char buf[516] = "";  //定义资源包
	char fileName[128] = "";  //定义文件名
	printf("请输入文件名:");
	scanf("%s",fileName);  
	getchar();
	
	//打开文件
	int fd = -1;
	if((fd = open(fileName,O_RDWR|O_CREAT|O_TRUNC|0666)) == -1)
	{
		perror("open error");  //读写形式创建文件,文件名为输入的文件名
		return -1;
	}

	//组装请求包
	short *p1 = (short *)buf;
	*p1 = htons(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);
	
	char *p5 = buf + 4; //确定数据的位置以及差错信息的位置

	while(1)
	{
		bzero(buf,sizeof(buf));
		int res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
		int A = buf[1];  //因为小端存储,操作码放在buf的第二位
		if(A == 3)  //当操作码为3时,证明是数据包,正常接收
		{
			write(fd,p5,sizeof(buf));
			buf[1]=4;   //将操作码改为4,即ACK
			//将buf前四位发送回去,因为操作码已经修改,发回去四位当做ACK回复
			sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin));
		}
		else if(A == 5)  //当操作码为5时,证明为ERROR
		{
			printf("%s\n",p5);
			return -1;
		}
		if(res < 516)  //当接收到的字节数小于516时,证明已经接收完成,关闭循环
			break;
	}
	printf("下载完成\n");
	close(fd);  //关闭文件
}

//实现上传功能
int upload(int cfd,struct sockaddr_in sin)
{
	char buf[516] = "";  //定义资源包
	char fileName[128] = "";  //定义文件名
	printf("请输入文件名:");
	scanf("%s",fileName);  
	getchar();
	
	//打开文件
	int fd = -1;
	if((fd = open(fileName,O_RDONLY)) == -1)
	{
		perror("open error");  //只读形式打开文件,文件名为输入的文件名
		return -1;
	}

	//组装请求包
	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 n = 1;
	while(1)
	{
		bzero(buf,sizeof(buf));
		recvfrom(cfd,buf,4,0,(struct sockaddr*)&sin,&socklen);
		int res = read(fd,buf+4,sizeof(buf)-4); //将文件的512位写入数据包
		buf[1]=3;   //将操作码改为3,即数据包
		
		//将buf发送,因为操作码已经修改,发回去数据加上了操作码和块编号
		sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin));
		if(res==0)  //证明已经上传完成,关闭循环
			break;
	}
	printf("上传完成\n");
	close(fd);  //关闭文件

}
int main(int argc, const char *argv[])
{
	if(argc != 2)
	{
		printf("input error");
		return -1;
	}

	//创建套接字
	int cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd == -1)
	{
		perror("socket error");
		return -1;
	}
	//填充服务器结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(69);
	sin.sin_addr.s_addr = inet_addr(argv[1]);

	int key = 0;
	while(1)
	{
		system("clear");
		printf("\t\t菜单\t\t\n");
		printf("\t\t1.下载\t\t\n");
		printf("\t\t2.上传\t\t\n");
		printf("\t\t0.关闭\t\t\n");
		printf("请输入选项:");
		scanf("%d",&key);
		getchar();
		switch(key)
		{
			case 1:
				{
					//下载
					int A =download(cfd,sin);

				};break;
			case 2:
				{
					//上传
					int B =upload(cfd,sin);
				};break;
			case 0:
				{
					goto A;
				};break;
			default:
				printf("请输入正确的选项!\n");
		}
		//阻塞
		printf("输入任意键,按回车清空");
		while(getchar() != '\n');
	}
	
A:
	close(cfd);


	return 0;
}

上传文件
在这里插入图片描述
下载文件
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/200484.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rocky Linux 9.3 为 PowerPC 64 位带回云和容器镜像

RHEL 克隆版 Rocky Linux 9.3 今天发布了&#xff0c;作为红帽企业 Linux 发行版 CentOS Stream 和 Red Hat Enterprise Linux 的免费替代版本&#xff0c;现在可供下载。 Rocky Linux 9.3 是在 Rocky Linux 9.2 发布 6 个月之后发布的&#xff0c;它带回了 PowerPC 64 位 Lit…

Java核心知识点整理大全22-笔记

目录 19.1.14. CAP 一致性&#xff08;C&#xff09;&#xff1a; 可用性&#xff08;A&#xff09;&#xff1a; 分区容忍性&#xff08;P&#xff09;&#xff1a; 20. 一致性算法 20.1.1. Paxos Paxos 三种角色&#xff1a;Proposer&#xff0c;Acceptor&#xff0c;L…

MySQL修改已存在数据的字符集

在实际应用中&#xff0c;如果一开始没有正确的设置字符集&#xff0c;在运行一段时间以后&#xff0c;才发现当前字符集不能满足要求&#xff0c;需要进行调整&#xff0c;但又不想丢弃这段时间的数据&#xff0c;这个时候就需要修改字符集。 在MySQL设置默认字符集和校对规则…

【飞桨星河社区五周年线下工坊-杭州站】

? 欢迎大家参加杭州极客工坊&#xff0c;深入了解大模型前沿技术和创新应用&#xff0c;一站式体验AI原生应用开发? 精彩议程敬请期待&#xff5e; ? 时间&#xff1a;2023年12月3日 14:00-17:30 ? 地点&#xff1a;杭州西湖区花蒋路3号西溪润泽园度假酒店 ? 主题&#xf…

C++中用于动态内存的new和delete操作符

文章目录 1、动态分配内存的应用2、动态分配内存与分配给普通变量的内存有什么不同?3、C 中如何分配/释放内存4、new 操作符4.1 使用new的语法4.2 初始化内存4.3 分配内存块4.4 普通数组声明 Vs 使用new4.5 如果运行时没有足够内存可用怎么办&#xff1f; 5、delete 操作符 C/…

第二十章Java博客

如果一次只完成一件事情&#xff0c;很容易实现。但现实生活中&#xff0c;很多事情都是同时进行的。Java中为了模拟这种状态&#xff0c;引入了线程机制。简单地说&#xff0c;当程序同时完成多件事情时&#xff0c;就是所谓的多线程。多线程应用相当广泛&#xff0c;使用多线…

喜报 | 再获影响力产品奖!擎创科技实力亮相GOPS全球运维大会

10月26日-27日&#xff0c;为期两天&#xff0c;共1100余人签到的 GOPS 全球运维大会 2023 上海站已经圆满落幕。 此次会议的“2023 IT技术领导力年度颁奖典礼”中&#xff0c;擎创夏洛克AIOps数智运维管理平台凭借成熟的产品能力及广泛且优异的落地实践效益&#xff0c;得到了…

记 Doris 回归测试S3导入load_parallelism > 1

增加load_parallelism > 1的S3导入用例&#xff0c;测试导入时切分输入文件的逻辑。 这里有几个隐性的问题点&#xff08;坑&#xff09;&#xff1a; 1、导入的文件一定要大&#xff0c;一般大于128M&#xff0c;否则&#xff0c;即使设置了 load_parallelism > 1 也不…

AI搜索相关性在网站和APP上的应用

设定场景&#xff1a;您在寻找一件新衣服&#xff0c;所以在浏览最喜欢的网店。您跳到搜索栏上&#xff0c;输入您要找的东西。您期待出现什么结果&#xff1f; 高度准确、相关和即时的结果。 无论在什么网站上搜索&#xff0c;寻找什么&#xff0c;甚至在打错字或使用了错误的…

JAVA进阶之路JVM-3:JVM内存模型,运行时数据区域划分,程序计数器,虚拟机栈,本地方法栈,堆,元空间,字符串常量池

JVM内存模型 对于 Java 程序员来说&#xff0c;在虚拟机自动内存管理机制下&#xff0c;不再需要像 C/C 程序开发程序员这样为每一个操作去写对应的 delete / free 操作&#xff0c;不容易出现内存泄漏和内存溢出问题。正是因为 Java 程序把内new存控制权利交给JVM虚拟机。一旦…

从源码解析Containerd容器启动流程

从源码解析Containerd容器启动流程 本文从源码的角度分析containerd容器启动流程以及相关功能的实现。 本篇containerd版本为v1.7.9。 更多文章访问 https://www.cyisme.top 本文从ctr run命令出发&#xff0c;分析containerd的容器启动流程。 ctr命令 查看文件cmd/ctr/comman…

高档建筑覆膜板,胶水足表面光滑

在建筑材料行业&#xff0c;选择高质量的建筑覆膜板至关重要。贵港市能强优品木业是专业从事建筑覆膜板生产销售25年的源头工厂。这家工厂一直以来致力于生产出色的覆膜板&#xff0c;以确保建筑物外观精美&#xff0c;持久耐用。 无论是商业大楼还是家庭住宅&#xff0c;外墙装…

气膜建筑助力体育场馆快速普及

传统的室内体育馆投入资金庞大&#xff0c;建设强度高&#xff0c;建设周期漫长。而气膜体育馆的出现&#xff0c;不仅显著降低了建设成本和缩短了建设周期&#xff0c;更符合节能环保的需求&#xff0c;成为推动场馆快速普及的创新建筑形式。 对于校园设施的建设而言&#xff…

可以免费使用的Axure在线版来了

Axure作为一种功能强大的原型设计工具&#xff0c;一直受到设计师的青睐。然而&#xff0c;其高昂的价格可能成为一个门槛&#xff0c;限制了一些设计师的选择。但不用担心&#xff0c;现在有一个免费的Axure在线工具即时设计&#xff0c;功能更完整&#xff0c;更划算&#xf…

『 MySQL数据库 』插入查询结果

文章目录 &#x1f39f;️ 前言&#x1f39f;️ 创建一张结构相同的表&#x1f39f;️ 表内插入查询结果&#x1f3ab; 对表内数据进行去重&#x1f3ab; 配合ORDER BY排序后以及LIMIT分页对数据进行插入 &#x1f39f;️ 前言 在MySQL数据库中不仅可以直接根据字段类型等对数据…

信而泰 SSL测试方法介绍

[本文介绍在ALPS平台上进行SSL测试的内容和方法] 什么是SSL SSL全称是Secure Sockets Layer&#xff0c;指安全套接字协议&#xff0c;为基于TCP的应用层协议提供安全连接&#xff1b;SSL介于TCP/IP协议栈的第四层和第五层之间&#xff0c;广泛用于电子商务、网上银行等。 SSL…

String你知道多少细节(含面试题)

1 字符串初始化 常见的初始化方式有以下3种 public static void main(String[] args) {String s1 "abc";System.out.println(s1);String s2 new String("abc");System.out.println(s2);char[] s3 {a,b,c};System.out.println(s3);} 【注意】 1.Strin…

【带头学C++】----- 八、C++面向对象编程 ---- 8.10 函数的默认参数

8.10 函数的默认参数 C在声明函数原型的时可为一个或者多个参数指定默认(缺省)的参数值&#xff0c;当函数调用的时候如果没有指定这个值&#xff0c;编器会自动用默认值代替。 通过为函数参数指定默认值&#xff0c;可以在调用函数时省略相应的参数&#xff0c;而该参数将使用…

自定义Windows服务启动失败

文章目录 自定义Windows服务启动失败报错内容解决方案管理员身份运行cmd进入到InstallUtil.exe的路径&#xff0c;使用cd命令。使用InstallUtil.exe工具安装服务。 自定义Windows服务启动失败 报错内容 “无法从命令行或调试器启动服务&#xff0c;必须首先安装Windows服务(使…

TikTok区块链实践:数字社交媒体的去中心化未来

随着区块链技术的日渐成熟&#xff0c;数字社交媒体行业也在探索如何整合区块链&#xff0c;以推动去中心化发展。在这一潮流中&#xff0c;TikTok作为全球领先的短视频平台&#xff0c;积极实践区块链技术&#xff0c;探索数字社交媒体的未来。本文将深入探讨TikTok的区块链实…