基于UDP的TFTP文件下载与上传
需求:
创建UDP客户端实现利用TFTP协议从服务器上下载文件与上传文件。
代码实现过程:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <pthread.h>#define ERR_MSG(msg) do{\fprintf(stderr,"line : %d\n",__LINE__);\perror("msg");\
}while(0)#define IP "192.168.8.130" //填本機ubantuIP ifconfig查看
#define PORT 69 //1024~49151#define FIL "download.png"char buf[600] = "";
ssize_t res = 0;
int sfd = 0;
socklen_t addrlen = 0;
short num = 0;
unsigned short numS = 1;void* funcS(void* arg){struct sockaddr_in sein = *((struct sockaddr_in*)arg);int fdS = open("upload.c",O_RDONLY);if(fdS < 0){ERR_MSG(open);return NULL;}while(1){bzero(buf,sizeof(buf));if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sein,&addrlen) < 0){ERR_MSG(recvfrom);return NULL;}bzero(buf,sizeof(buf));sprintf(buf,"%c%c",0,3);*(short*)(buf+2) = htons(numS);// *(short*)(buf+2) = htons(numS);res = read(fdS,buf+4,512);printf("numS = %d htons(numS) = %d num = %d res = %ld\n",numS,htons(numS),num,res);if(res < 0){ERR_MSG(read);return NULL;}// printf("buf = %s\n",buf+4);if(sendto(sfd,buf,res+4,0,(struct sockaddr*)&sein,sizeof(sein)) < 0){ERR_MSG(sendto);return NULL;}if(res != 512){printf("文件上传完毕\n");break;}numS++;}
}void* funcR(void* arg){struct sockaddr_in sein = *((struct sockaddr_in*)arg);int flag = 0;int fdR = -1;unsigned short numC = 0;while(1){//接受if(0 == flag){fdR = open(FIL,O_RDWR|O_CREAT|O_TRUNC,0664);if(fdR < 0){ERR_MSG(open);return NULL;} flag=1;}//UDP是无连接不可靠的,数据包可能会重复接收到的通信//可以在本地记录每次收到的包的编号//如果本地记录的包的编号与数据包发送回来的块编号不一致,则不处理//if(htons(numC+1) == *(unsigned short*)(buf+2)){bzero(buf,sizeof(buf));res = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sein,&addrlen);short *p1 = (short*)(buf+2);num = ntohs(*p1);printf("num = %d res = %ld\n",num,res);if(res < 0){ERR_MSG(recv);return NULL;}if(write(fdR,buf+4,res-4) < 0){ERR_MSG(write);return NULL;}bzero(buf,sizeof(buf));short *p2 = (short*)buf;*p2 = htons(4);short *p3 = p2+1;*p3 = htons(num);if(sendto(sfd,buf,4,0,(struct sockaddr*)&sein,sizeof(sein)) < 0){ERR_MSG(sendto);return NULL;}if(res!=516){fprintf(stderr,"文件下载完毕\n");close(fdR);break;}numC++;//}}
}int main(int argc, const char *argv[])
{//創建报式套接字sfd = socket(AF_INET,SOCK_DGRAM,0);if(sfd < 0){ERR_MSG(socket);return -1;}//填充地址信息結構體//根據地址族的不同,地址信息結構體不一致,AF_INET:man 7 ipstruct sockaddr_in sein;sein.sin_family = AF_INET; //必須填AF_INETsein.sin_port = htons(PORT); //端口號的網絡字節序,1024~49151sein.sin_addr.s_addr = inet_addr(IP); //本機IP地址的網絡字節序,ifconfigaddrlen = sizeof(sein);char choose = 0;int size = 0;pthread_t tidS,tidR;while(1){printf("-------------------------\n");printf("---------1.download------\n");printf("---------2.upload--------\n");printf("---------3.exit----------\n");printf("-------------------------\n");printf("请输入>>>");choose = getchar();getchar();switch(choose){case '1'://do_download//发送下载请求 bzero(buf,sizeof(buf));size = sprintf(buf,"%c%c%s%c%s%c",0,1,"5.png",0,"octet",0);printf("buf = %s size = %d \n",buf+1,size);if(sendto(sfd,buf,size,0,(struct sockaddr*)&sein,sizeof(sein)) < 0){ERR_MSG(send);return 0;}printf("send success\n");if( pthread_create(&tidR,NULL,funcR,&sein) != 0){ERR_MSG(pthread_create);return -1;}pthread_join(tidR,NULL);break;case '2'://do_upload发送上传请求bzero(buf,sizeof(buf));size = sprintf(buf,"%c%c%s%c%s%c",0,2,"upload.c",0,"octet",0);if(sendto(sfd,buf,size,0,(struct sockaddr*)&sein,sizeof(sein)) < 0){ERR_MSG(send);return 0;}printf("send success\n");if( pthread_create(&tidS,NULL,funcS,&sein) != 0){ERR_MSG(pthread_create);return -1;}pthread_join(tidS,NULL);break;case '3':printf("程序退出\n");return 0;}}close(sfd);return 0;
}
代码实现结果:
基于UDP的TFTP文件下载与上传相关推荐
- 基于华为云obs实现文件上传下载(技术栈mysql+springboot+Maven+jsp+java)的技术分享
基于华为云obs实现文件上传下载(技术栈mysql+springboot+jsp+java)的技术分享 obs实现文件上传下载 前言 一.OBS是什么? 二.使用步骤 1.1 前期准备 2 工具的内容 ...
- tftp在put上传的时候显示File not found的解决办法
tftp在put上传的时候显示File not found的解决办法 在linux下,不管使用的是哪一种super-server,inetd或者xinetd,默认情况下TFTP服务是禁用的,所以要修改 ...
- ASP.NET Web API实现简单的文件下载与上传
ASP.NET Web API实现简单的文件下载与上传.首先创建一个ASP.NET Web API项目,然后在项目下创建FileRoot目录并在该目录下创建ReportTemplate.xlsx文件, ...
- antd的联级选择器异步调用编辑回显_react-uplod-img 是一个基于 React antd组件的图片上传组件...
react-uplod-img 是一个基于 React antd组件的图片上传组件 支持oss qiniu等服务端自定义获取签名,批量上传, 预览, 删除, 图片精确的尺寸限制 排序等功能 需要 re ...
- 前端基于element组件的语音文件上传
前端基于element组件的语音文件上传 原理 项目采用的是element组件的UI库,基于标签,实现基本的文件上传功能,并基于标签内置的触发事件,实现了对语音文件大小,格式,上传前确认,上传后显示已 ...
- 学习日志day41(2021-09-03)(1、文件的上传 2、文件的查看 3、文件的下载 4、使用工具类上传文件 5、基于servlet3.0以上的文件上传 )
学习内容:学习JavaWeb(Day41) 1.文件的上传 2.文件的查看 3.文件的下载 4.使用工具类上传文件 5.基于servlet3.0以上的文件上传 1.文件的上传 (1)实现文件的上传需要 ...
- 基于element-ui的图片转码上传服务器
毕业后回公司搬砖了,今天记录一下基于element-ui的图片转码上传问题.先说一下页面逻辑,上传图片到服务器,先把图片和图片信息转码成字符串,然后传给后台. 先看看页面实现的效果: 这里用的 ...
- 基于fastDFS和elementUI的文件上传(只要后端有数据,一通百通。)
基于elementUI和fastDFS的文件上传 只要数据传到后端,啥都好说,进不去白瞎,所以不管是fastDFS还是别的,一通百通(只是时间问题) 准备 <dependency>< ...
- [C# 网络编程系列]专题十一:实现一个基于FTP协议的程序——文件上传下载器...
引言: 在这个专题将为大家揭开下FTP这个协议的面纱,其实学习知识和生活中的例子都是很相通的,就拿这个专题来说,要了解FTP协议然后根据FTP协议实现一个文件下载器,就和和追MM是差不多的过程的,相信 ...
最新文章
- python【蓝桥杯vip练习题库】BASIC-11 十六进制转十进制
- nema0183 java解析_NEMA 0183 语句解析
- C#操作Access数据库
- Atom React或前端插件推荐
- js中 switch 注意事项
- 中职学校计算机教学参考文献,学生计算机论文,关于中职学校计算机专业教学现状相关参考文献资料-免费论文范文...
- Atitit 开发效率的提升艺术 艾提拉著 目录 1. 主要几个层次上简化开发	2 1.1. 管理创新	2 1.2. 开发体系方法使用简单方法	2 1.3. 技术选型使用简单框架模式	2 1.4.
- allergo 命令
- 彻底删除浏览器毒霸首页
- “不学数学就去当厨子”,兰大校友入选全球竞赛最强10人,决赛最后几小时才想起做题...
- C# async / await 任务超时处理
- 我的RUST学习 ——【第九章 9-2】Result 与 可恢复的错误
- 小程序快递单号查询接口物流助手对接指南
- 成为人生的赢家都有哪些书_那么,我们是否有代码挑战#1的赢家?
- POJ-3426-0-1背包Charm Bracelet
- OpenStack T版服务组件--Keyston身份服务
- 龙芯版UOS 自带浏览器无法使用flash在线播放视频
- AAL模板及脑区功能介绍
- MFC程序最小化到托盘
- 文件IO中read()函数读取输出字符串有乱码