【网络编程】基于UDP的TFTP文件传输

news2024/9/22 9:56:27

1)tftp协议概述

简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输

特点:

是应用层协议

基于UDP协议实现

数据传输模式

octet:二进制模式(常用)

mail:已经不再支持

2)tftp下载模型

TFTP通信过程总结

  1. 服务器在69号端口等待客户端的请求
  2. 服务器若批准此请求,则使用 临时端口 与客户端进行通信。
  3. 每个数据包的编号都有变化(从1开始)
  4. 每个数据包都要得到ACK的确认,如果出现超时,则需要重新发送最后的数据包或ACK包
  5. 数据长度以512Byte传输的,小于512Byte的数据意味着数据传输结束。

 

代码实现

main.c

#include"tftp.h"

int main(int argc, const char *argv[])
{
	int cmd  = 0;//用来标记操作
	char filename[20] = "";//存放文件名
	int cfd = socket(AF_INET,SOCK_DGRAM,0);//创建套接字文件
	if(cfd == -1)
	{
		perror("socket error");
		return -1;
	}
	while(1)
	{
		menu();
		printf("请输入要执行的操作:");
		scanf("%d",&cmd);
		switch(cmd)
		{
			case 1:
				printf("请输入文件名:");
				scanf("%s",filename);
				download(cfd,filename);
				break;
			case 2:
				printf("请输入文件名:");
				scanf("%s",filename);
				upload(cfd,filename);
				break;
			case 3:
				printf("退出\n");
				goto END;
				break;
			default:
				printf("输入错误\n");
				break;
		}
	}
END:
	//关闭文件描述符
	close(cfd);
	return 0;
}

tftp.c

#include"tftp.h"
//菜单
void menu()
{
	printf("-------------------------\n");
	printf("--------1.下载文件--------\n");
	printf("--------2.上传文件--------\n");
	printf("--------3.退出------------\n");
	printf("-------------------------\n");
}

//上传
int upload(int cfd , char *filename)
{
	char buf[N] = "";
	short *p1 = (short*)buf;
	*p1 = htons(2);//设置操作码为2,表示上传

	char *p2 = buf + 2;//文件名的起始位置
	strcpy(p2,filename);

	char *p4 = p2 + strlen(p2) + 1;//模式的起始位置
	strcpy(p4,"octet");

	int size = 2 + strlen(p2) + strlen(p4) + 2;//计算请求包的总长度
	
	//打开本地文件
	int fd = open(filename,O_RDONLY);
	if(fd == -1)
	{
		perror("open error");
		return -1;
	}
	//绑定服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	socklen_t len = sizeof(sin);
	//给服务段发送请求
	if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("sendto error");
		return -1;
	}	
	short flag = 1;//设置标示位
	
	//收发数据
	while(1)
	{
		//清空数据
		bzero(buf,sizeof(buf));
		if(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&len)==-1)
		{
			perror("recvfrom error");
			return -1;
		}
		//将ack改造成为数据包
		if(buf[1] == 4 || flag == buf[2])
		{
			int res = read(fd,buf+4,sizeof(buf)-4);//从buf的5个开始放数据,读取buf-4个数据
			if(res < 0)
			{
				perror("read error");
				return -1;
			}
			if(res == 0)
			{
				printf("文件发送完毕\n");
				return -1;
			}
			buf[1]=3;
			buf[3] = flag;
			if(sendto(cfd,buf,res+4,0,(struct sockaddr*)&sin,sizeof(sin)) == -1)
			{
				perror("sendto error");
				return -1;
			}	
			flag++;
		}
		if(buf[1] == 5)
		{
			printf("接收错误\n");
			break;
		}
	}
}

//下载
int download(int cfd ,char *filename)
{
	char buf[N] = "";
	short *p1 = (short*)buf;
	*p1 = htons(1);//设置操作码为1,表示下载

	char *p2 = buf + 2;//文件名的起始位置
	strcpy(p2,filename);

	char *p4 = p2 + strlen(p2) + 1;//模式的起始位置
	strcpy(p4,"octet");

	int size = 2 + strlen(p2) + strlen(p4) + 2;//计算请求包的总长度
	
	//创建本地文件
	int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0644);
	if(fd == -1)
	{
		perror("open error");
		return -1;
	}
	//绑定服务器地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
	sin.sin_addr.s_addr = inet_addr(SER_IP);
	socklen_t len = sizeof(sin);
	//给服务段发送请求
	if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("sendto error");
		return -1;
	}	
	short flag = 1;//设置标示位
	while(1)
	{
		//清空
		bzero(buf,sizeof(buf));
		//获取服务器发来的包
		int res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&len);
		if(res == -1)
		{
			perror("recvfrom error");
			return -1;
		}
		//判断是否是数据包
		if(buf[1] == 3 && flag == ntohs(*(short*)(buf+2)))
		{
			//将数据写入文件中
			if(write(fd,buf+4,N-4)==-1)
			{
				perror("write error");
				return -1;
			}
			//返回ack
			buf[1] = 4; 
			if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
			{
				perror("sendto error");
				return -1;
			}
			flag++;//确保和需要的块编号一致
		}
		//判断是否是错误包
		if(buf[1] == 5)
		{
			printf("文件发送错误\n");
		}
		//判断是否发送完毕
		if(res < 516)
		{
			printf("文件接收完毕\n");
			return -1;
		}

	}
}

tftp.h

#ifndef TFTP_H
#define TFTP_H
#define SER_PORT 69
#define SER_IP "192.168.1.4"
#define N 516
#include<myhead.h>
//菜单
void menu();

//上传
int upload(int cfd , char *filename);

//下载
int download(int cfd ,char *filename);


#endif

效果展示

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习入门:卷积神经网络 | CNN概述,图像基础知识,卷积层,池化层(还在等什么!!!超详解!!!)

目录 &#x1f354; 前言 &#x1f354; 图像基础知识 1. 像素和通道的理解 2. 小节 &#x1f354; 卷积层 1. 卷积计算 2. Padding 3. Stride 4. 多通道卷积计算 5. 多卷积核卷积计算 6. 特征图大小 7. PyTorch 卷积层 API 7. 小节 &#x1f354; 池化层 1. 池…

WEB之文件上传

一&#xff1a;思维导图 二&#xff1a;相关问题解答 1&#xff0c;什么是文件上传漏洞? 文件上传漏洞是一种常见的网络安全问题&#xff0c;它发生在网络应用程序允许用户上传文件到服务器的功能中。如果这一功能没有得到适当的安全控制和验证&#xff0c;攻击者就可以利用…

web开发,过滤器,前后端交互

目录 web开发概述 web开发环境搭建 Servlet概述 Servlet的作用&#xff1a; Servlet创建和使用 Servlet生命周期 http请求 过滤器 过滤器的使用场景&#xff1a; 通过Filter接口来实现&#xff1a; 前后端项目之间的交互&#xff1a; 1、同步请求 2、异步请求 优化…

利用telnet发送QQ邮箱的电子邮件时遇到的问题(2024最新)

问题1&#xff1a;即使在控制面板启用telnet客户端也无法使用telnet 解决&#xff1a;使用管理员权限打开cmd&#xff0c;执行命令&#xff1a;dism /online /Enable-Feature /FeatureName:TelnetClient&#xff0c;之后根据弹出信息键入Y重启即可 参考链接&#xff1a;https:…

开源新宠:RAG2SQL工具,超越Text2SQL的7K Star之作

查询数据库离不开SQL&#xff0c;那如何快速构建符合自己期望的SQL呢&#xff1f;AI发展带来了Text2SQL的能力&#xff0c;众多产品纷纷提供了很好的支持。 今天我们分享一个开源项目&#xff0c;它在Text2SQL的基础上还要继续提高&#xff0c;通过加入RAG的能力进一步增强&am…

虹软科技25届校招笔试算法 A卷

目录 1. 第一题2. 第二题3. 论述题 ⏰ 时间&#xff1a;2024/08/18 &#x1f504; 输入输出&#xff1a;ACM格式 ⏳ 时长&#xff1a;2h 本试卷分为不定项选择&#xff0c;编程题&#xff0c;必做论述题和选做论述题&#xff0c;这里只展示编程题和必做论述题&#xff0c;一共三…

代码随想录算法训练营_day17

题目信息 654. 最大二叉树 题目链接: https://leetcode.cn/problems/maximum-binary-tree/题目描述: 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前…

AVI-Talking——能通过语音生成很自然的 3D 说话面孔

概述 论文地址&#xff1a;https://arxiv.org/pdf/2402.16124v1.pdf 逼真的人脸三维动画在娱乐业中至关重要&#xff0c;包括数字人物动画、电影视觉配音和虚拟化身的创建。以往的研究曾试图建立动态头部姿势与音频节奏之间的关联模型&#xff0c;或使用情感标签或视频剪辑作…

【数据结构与算法】如何构建最小堆

最小堆的定义 最小堆&#xff0c;作为一种独特且重要的数据结构&#xff0c;它是一种特殊的二叉树。在这种二叉树中&#xff0c;有一个关键的规则&#xff1a;每一个父节点所存储的值&#xff0c;都必然小于或者等于其对应的子节点的值。这一规则确保了根节点总是承载着整个堆…

机器学习(3)-- 一元线性回归

文章目录 线性回归训练模型测试模型线性回归方程测试实用性 总结 线性回归 线性回归算法是一种用于预测一个或多个自变量&#xff08;解释变量&#xff09;与因变量&#xff08;响应变量&#xff09;之间关系的统计方法。这种方法基于线性假设&#xff0c;即因变量是自变量的线…

【学习笔记】Day 16-17

一、进度概述 1、ddnet_main 相关代码学习&#xff08;预计 3-4 天&#xff09; 二、详情 1、顶层结构 关于代码顶层结构的一些思考和总结&#xff0c;其中下图为师兄代码的文件结构 总结&#xff1a; 对于一个优秀的代码&#xff0c;其文件结构一定也是清晰的&#…

随笔五、开发板连接WIFI并通过SSH连接泰山派

摘要&#xff1a;通过wifi连接内网&#xff0c;电脑通过SSH连接泰山派 1. 泰山派接入WIFI 泰山派开发板SDK已经集成wifi_start.sh脚本&#xff0c;在脚本后面直接输入wifi名字和密码就能连接wifi rootRK356X:/# wifi_start.sh wifi名字 wifi密码 查看ip地址&#xff0c;wlan0就…

洛谷 P6359 [CEOI2018] Cloud computing

题目本质&#xff1a;贪心01背包&#xff08;dp&#xff09; 题目思路&#xff1a;dp[i][j] 表示考虑前 i 台计算机&#xff0c;能够获得 j 个核心时&#xff0c;所能获得的最大价值。将其可以优化为dp[i] 表示能够获得 i 个核心时&#xff0c;所能获得的最大价值。 状态转移…

jira敏捷开发管理工具视频教程Confluence工作流协同开发(2024)

正文&#xff1a; 随着Jira敏捷开发方法论的普及&#xff0c;Jira已经成为全球软件开发团队管理项目、任务和问题的首选工具。为了帮助团队更好地掌握Jira的核心功能&#xff0c;精心准备了一套全面开发技术及案例视频教程——《Jira敏捷开发管理工具视频教程Confluenc…

学习大数据DAY38 hive 安装与配置

目录 hadoop 大数据平台-hive 组件部署介绍 hadoop 大数据平台-Hive 部署步骤 教学视频 上机作业 hadoop 大数据平台-hive 组件部署介绍 metastore:保存关于表、列、分区、数据格式、存储位置等各种元数据信 Driver:负责与 Hive 服务器建立网络连接&#xff0c;使客户端能…

Unity的动画系统

目录 Unity动画系统的最新更新和改进有哪些&#xff1f; 如何在Unity中高效地使用Animator组件进行复杂动画制作&#xff1f; Unity动画系统中的动画混合和分层功能是如何工作的&#xff1f; 动画混合&#xff08; blend tree&#xff09; 动画分层 在Unity中创建和管理动…

一键运行RocketMQ5.3和Dashboard

一键运行RocketMQ5.3和Dashboard 目录 一键运行RocketMQ5.3和Dashboard通过Docker Compose 来一键启动运行的容器包括docker-compose.yml文件运行命令启动本地效果查看 参考信息 通过Docker Compose 来一键启动 运行的容器包括 NameServerBrokerProxyDashBoard docker-compo…

RabbitMQ消息队列总结(❤❤❤❤❤)

RabbitMQ那些事 参考一. `RabbitMQ`介绍1.1 Java工程师1.1.1 RabbitMQ学习目标1.1.2 消息队列介绍1.1.3 RabbitMQ介绍各自属性介绍(❤❤❤)二. `RabbitMQ`安装1. 基于Linux1.1 安装1.2 常用命令1.3 后台管理开启与面板介绍三. 客户端`SDK`操作(❤❤了解)1. 客户端依赖2. 生产者…

微信消息防撤回插件

该软件可以恢复别人撤回的消息。 版本特色&#xff1a; 1、看到对方撤回的消息 2、多账号可正常登录 修改原理&#xff0c;如下图&#xff1a; 使用说明&#xff1a; 1、需电脑登录 2、解压后&#xff0c;双击start_wechat.bat来运行软件 下载地址&#xff1a;Wechat防撤…

UE基础 —— 资产和内容包

目录 直接导入资产 使用资产 创建资产 资产引用 管理资产 移动和复制资产 删除资产 导出资产 迁移资产 资产元数据 在虚幻编辑器UI中使用元数据 使用资产元数据 自动重新导入 查找资产引用 替换引用工具 Class Viewer 全局资产选取器 Property Matrix 引擎项…