基于UDP的TFTP文件传输-实现网盘上传下载功能

数据传输模式:octet(二进制模式)

#include<head.h>
char* down_up_request(char* buf,char* filename,int rw,int sockfd,struct sockaddr_in in);
int download(struct sockaddr_in in,char* filename,char* buf,int sockfd);
int upload(struct sockaddr_in in,char* filename,char* buf,int sockfd);
int main(int argc, const char *argv[])
{/***********************************基于UDF的TFTP文件传输,实现网盘功能***********************************//**********客户端代码**************///创建套接文件int rtsocket=socket(AF_INET,SOCK_DGRAM,0);if(rtsocket==-1){perror("socket");return -1;}else{printf("套接文件创建成功\n");}//绑定客户端端口与IPstruct sockaddr_in cin;char* cip="192.168.176.130";uint16_t cport=8888;cin.sin_family=AF_INET;cin.sin_port=htons(cport);cin.sin_addr.s_addr=inet_addr(cip);int rtbind=bind(rtsocket,(struct sockaddr*)&cin,sizeof(cin));if(rtbind==0){printf("与客户端绑定成功\n");}else if(rtbind==-1){perror("bind");return -1;}//数据收发/*填充服务器地址与端口信息*/struct sockaddr_in sin;char* sip="192.168.118.161";uint16_t sport=69;sin.sin_family=AF_INET;sin.sin_port=htons(sport);sin.sin_addr.s_addr=inet_addr(sip);/*********************************/char data[516]={0};char filename[128]={0};printf("*******1<download>*******\n");printf("*******2<upload>*********\n");printf("*******3<exit>***********\n");while(1){int option=0;printf("please choose option:");scanf("%d",&option);if(option<1&&option>3){printf("enter error,please reenter\n");scanf("%d",&option);}switch(option){case 1 :{printf("please enter download filename:");scanf("%s",filename);getchar();char* rt=down_up_request(data,filename,1,rtsocket,sin);download(sin,filename,rt,rtsocket);}break;case 2:{printf("please enter upload filename:");scanf("%s",filename);getchar();char* rt=down_up_request(data,filename,2,rtsocket,sin);upload(sin,filename,rt,rtsocket);}break;case 3: {goto END;}break;}}
END:close(rtsocket);return 0;
}
//下载或上传请求
char* down_up_request(char* buf,char* filename,int rw,int sockfd,struct sockaddr_in in){short* p1=(short*)buf;*p1=htons(rw);//rw操作码转为网络字节序char* p2=buf+2;strcpy(p2,filename);//存入要下载的文件名char* p3=p2+strlen(p2)+1;strcpy(p3,"octet");//设置操作模式int size=2+sizeof(p2)+1+sizeof(p3)+1;ssize_t rtsendto=sendto(sockfd,buf,size,0,(struct sockaddr*)&in,sizeof(in));if(rtsendto==-1){perror("sendto");return NULL;}else{printf("发送请求成功\n");}return buf;
}
//下载
int download(struct sockaddr_in in,char* filename,char* buf,int sockfd){int fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd==-1){perror("open");return -1;}short num=0;socklen_t addrlen=sizeof(in);while(1){bzero(buf,sizeof(buf));ssize_t rtrecvfrom=recvfrom(sockfd,buf,516,0,(struct sockaddr*)&in,&addrlen);//循环接收数据if(rtrecvfrom==-1){perror("recvfrom");return -1;}else{printf("reading......\n");}if(buf[1]==3){//判断是否是数据包if(*(short*)(buf+2)==htons(num+1)){//确认块编号接发是否一致num++;if(rtrecvfrom-4==512){//数据包后512字节为数据ssize_t rtwrite=write(fd,buf+4,rtrecvfrom-4);if(rtwrite<0){printf("write error\n");break;}}char ACK[4]={0};short *p=(short*)ACK;*p=htons(4);short *p1=(short*)(ACK+2);*p1=htons(num);ssize_t rtsendto=sendto(sockfd,ACK,4,0,(struct sockaddr*)&in,addrlen);//写入成功,向服务器发送ACK,确认if(rtsendto==-1){perror("sendto");return -1;}if(rtrecvfrom<516){//读取小于516说明已经读取结束ssize_t rtwrite=write(fd,buf+4,rtrecvfrom-4);if(rtwrite<0){printf("write error\n");break;}printf("end of download\n"); close(fd);  break;}}} else if(buf[1]==5){ //错误信息printf("error:%s\n",buf+4);close(fd);return -1;}}
}
//上传
int upload(struct sockaddr_in in,char* filename,char* buf,int sockfd){int fd=open(filename,O_RDONLY);if(fd==-1){printf("file don't exist\n");return -1;}short num=0;socklen_t addrlen=sizeof(in);while(1){bzero(buf,sizeof(buf));ssize_t rtrecvfrom=recvfrom(sockfd,buf,4,0,(struct sockaddr*)&in,&addrlen);//循环接收服务器确认消息if(rtrecvfrom==-1){perror("recvfrom");return -1;}else{printf("ready upload....\n");}//	printf("ACK=%d\n",ntohs(*(short*)(buf+2)));//查看第一次发过来的ack//	解析服务器数据,读取并发送数据包给服务器if(buf[1]==4){//判断服务器是否发来ACKif(*(short*)(buf+2)==htons(num)){//确认块编号接发是否一致,从0开始ssize_t rtread=read(fd,buf+4,512);printf("uploading.......\n");//	printf("rtread=%ld\n",rtread);short *p=(short*)buf;*p=htons(3);//修改为数据包,服务器识别数据包下载数据num++;//ACK块编码确认+1给服务器确认short *p1=(short*)(buf+2);*p1=htons(num);ssize_t rtsendto=sendto(sockfd,buf,rtread+4,0,(struct sockaddr*)&in,addrlen);//将上传的文件以每512字节发送给服务器,并发送ACK确认if(rtsendto==-1){perror("sendto");return -1;}if(rtread<512){//读取小于512说明上传的文件已经读取完毕printf("upload success\n");close(fd);break;}}}else if(buf[1]==5){ //错误信息printf("error:%s\n",buf+4);close(fd);return -1;}}
}

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

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

相关文章

百川大模型拿下国产第一,AI助手「百小应」上线,比Kimi强不少

最近几天&#xff0c;国内 AI 创业公司正在连续刷新大模型的能力上限。 5 月 22 日&#xff0c;百川智能发布最新一代基座大模型 Baichuan 4&#xff0c;同时推出了首款 AI 助手「百小应」。 相较 1 月份发布的 Baichuan 3&#xff0c;新一代模型在各项能力上均有大幅提升&am…

如何与“病态”的人建立友谊:一种基于理解与接纳的视角

在我们的生活中&#xff0c;我们经常会遇到一些行为举止让我们感到不适或难以理解的人。这些人可能因为他们的某些行为被标签为“病态”&#xff0c;但真的应该如此简单地对他们进行评判吗&#xff1f;本文将探讨如何与被视为“病态”的人建立友谊&#xff0c;以及为什么这种接…

【云擎未来,智信天下】移动云服务器Docker部署+远程连接Redis

文章目录 引言&#xff1a; 移动云&#xff1a;云擎未来&#xff0c;智信天下一、什么是Redis&#xff1f;二、Redis 与其他 key-value 存储有什么不同&#xff1f;Redis 架构 三、环境准备四、部署流程使用Redis Desktop Manager远程连接操作数据库总结与未来展望云擎未来&…

java nio FileChannel堆内堆外数据读写全流程分析及使用(附详细流程图)

这里是小奏,觉得文章不错可以关注公众号小奏技术 背景 java nio中文件读写不管是普通文件读写&#xff0c;还是基于mmap实现零拷贝&#xff0c;都离不开FileChannel这个类。 随便打开RocketMQ 源码搜索FileChannel 就可以看到使用频率 kafka也是 所以在java中文件读写FileCh…

集合的概述

java集合框架(Java Collections Framework)为开发者提供了一系列通用容器&#xff0c;所谓容器就是可以容纳其他对象的对象&#xff0c;在jdk1.2开始&#xff0c;就提供了通用容器。 1.Java集合框架的概述 容器是用于容纳其他对象的对象&#xff0c;因此基本数据类型无法直接使…

聚数力 以数兴 | 与“闽”同行,共话数字未来

闽江之畔&#xff0c;数智腾飞。5月24日&#xff0c;第七届数字中国建设峰会在海峡国际会展中心盛大举办。本届展会的主题是“释放数据要素价值&#xff0c;发展新质生产力”&#xff0c;由国家发展改革委、国家数据局、福建省人民政府等单位共同主办&#xff0c;福州市人民政府…

数据恢复的救星!快速恢复手机数据的2个秘籍!

当我们的照片、视频、联系人、短信和应用程序丢失时&#xff0c;许多人可能会感到束手无策&#xff0c;无论是珍贵的照片、重要的工作文件还是个人的联系方式&#xff0c;一旦丢失&#xff0c;都可能带来极大的不便和困扰。但随着数据恢复技术的发展&#xff0c;我们有了更多的…

锐捷网络与您相约第七届数字中国建设峰会 共话数字未来

第七届数字中国建设峰会将于5月24日至25日在福建福州举办,本届峰会是国家数据工作体系优化调整后首次举办的数字中国建设峰会,主题是“释放数据要素价值,发展新质生产力”。作为行业领先的ICT基础设施及解决方案提供商,锐捷网络与福建省电子信息集团、星网锐捷,围绕“发展新质生…

2024中青杯数学建模竞赛A题人工智能视域下养老辅助系统的构建思路代码论文分析

2024中青杯数学建模A题论文和代码已完成&#xff0c;代码为A题全部问题的代码&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&#xff08;问题1模型的建立和求解、问题2模型的建立和求解、问题3模型的建立和求解&#xff09;、模型的评价…

用go语言实现一个有界协程池

写在文章开头 本篇文章算是对go语言系列的一个收尾&#xff0c;通过go语言实现一个实现一个简单的有界协程池。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核技术上作死的 java coder &#xff0c;是 CSDN的博客专家 &#xff0c;也是开源项目 Java Guide 的维护…

HDR视频相关标准-HDR vivid(二)

上文介绍了HDRvivid的一些技术。今天从全局角度来看看HDR视频的处理流程&#xff0c;HDR视频系统&#xff0c;即建立一个比SDR视频更大的色彩/亮度坐标体系&#xff0c;并改变系统的传输函数&#xff0c;以再现更大的色域(WCG)和更高的亮度动态范围。 菁彩 HDR技术的专业术语 …

【ROSUbuntu】常用工具合集

1. 源 ADM64 ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror arm64 ubuntu-ports | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 2. FileZilla sudo apt-get install filezilla 3. Nomachine8 AMD64

操作系统实战(四)(linux+C语言)

目录 实验目的 前提知识 实验题目 题目分析 实验程序 头文件 头文件实现 核心代码文件 &#xff08;各类进程&#xff09; 生产者 抽烟者A 抽烟者B 抽烟者C makefile文件 实验运行 运行结果分析 总结 实验目的 加深对并发协作进程同步与互斥概念的理解&…

Jenkins配置(插件/角色/凭证)

目录 传送门前言一、Jenkins插件管理1、更换为国内下载源2、中文汉化插件下载&#xff08;不推荐&#xff09;3、低版本Jenkins爆红插件安装4、低版本Jenkins插件持续报错解决办法 二、Jenkins用户角色三、Jenkins凭证管理&#xff08;svn/git&#xff09;1、Username with pas…

NIO流(多路复用技术)

目录 什么是NIO使用场景 NIO(new IO)相关包路径NIO的实现基础NIO的核心组件Buffer缓冲区详解数据如何从磁盘读到用户进程 ChannelChannel的使用 其他组件字符集和Charset文件锁NIO工具类使用Files的FileVisitor遍历文件和目录使用WatchService监控文件变化访问文件属性 什么是N…

什么样的无线麦克风好?一文看懂哪种麦克风降噪效果好

作为视频创作者&#xff0c;拍摄视频除了要注意拍摄的画质外&#xff0c;声音的录制也很重要。声音录制的清晰度也会直接影响整个作品的整体水平&#xff0c;要想录的声音清晰&#xff0c;有专业级录制效果&#xff0c;必须选好麦克风&#xff0c;而无线领夹麦克风&#xff0c;…

【工具分享】Annabelle勒索病毒解密工具

前言 Annabelle勒索病毒灵感来自恐怖电影系列 Annabelle。除了文件加密功能外&#xff0c;Annabelle 勒索软件还会试图禁用防火墙&#xff0c;强制停止一系列正在运行程序&#xff0c;通过连接的 USB 驱动器进行传播。 特征 勒索内容&#xff1a; Annabelle 使用 AES256 CBC 加…

【Linux】线程同步和生产者-消费者模型

目录 一. 线程同步1. 条件变量2. 条件变量接口条件变量的创建及初始化条件变量的销毁条件变量等待条件变量唤醒 3. 条件变量同步解决抢占问题 二. 生产者-消费者模型1. 什么是生产者-消费者模型2. 为什么要使用生产者-消费者模型3. 生产者-消费者模型特点4. 基于阻塞队列实现生…

技术前沿:三品PLM系统引领工程变更管理新趋势

引言 在当今快速变化的制造行业&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统已成为企业不可或缺的工具之一。PLM系统不仅帮助企业优化产品开发流程&#xff0c;还对工程变更管理&#xff08;ECM&#xff09;起着至关重要的作用。本文将探讨PLM系统在工程变更…

解决ssh报错,.ssh/id_rsa: No such file or directory Permission denied (publickey)

拉取依赖或者代码时说没有权限 首先我们可以看到的是这个报错但是我们的远程确实配置ssh密钥 首先我们可以看到的是这个报错 但是我们的远程确实配置ssh密钥 我们可以在我们项目路径下添加一下我们的私钥如&#xff1a; 首先确定我们ssh是正常启动的eval $(ssh-agent)我们可以…