9.12 TFTP通信

客户端设计(仅供参考):

下载本质:读取服务器发送的数据包,写入到本地文件
上传本质:读取本地文件内容,发送给服务器。
1、建立菜单选项,上传和下载。
2、上传功能函数:
1、只读打开本地文件
2、发送上传请求数据包
3、接收服务器应答并回复ACK包
3、1如果接收的是ACK确认包,将包修改为数据包填充本地文件内容并发送给服务器
3、2如果是错误包,上传结束,检查网络。
3、下载功能函数
1、发送下载请求包
2、循环接收服务器数据包
2.1判断收到的包如果是数据包并且块编号正确,就写入客户端文件,然后回复ACK确认包
2.2如果包的长度小于512+2+2,说明接收完毕
2.3如果是错误包。输出对应错误信息并停止接收。

TFTP下载模型:

在这里插入图片描述

TFTP上传模型

在这里插入图片描述

TFTP通信过程总结

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

do_upload(上传文件)

void do_upload(int sockfd,struct sockaddr_in sin,const char *filename){char text[1024] = "";int text_len;socklen_t sinlen = sizeof(sin);int fd;int flags = 0;int num = 0;ssize_t bytes;text_len = sprintf(text,"%c%c%s%c%s%c",0,2,filename,0,"octet",0);if(sendto(sockfd,text,text_len,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}while(1){if((bytes = recvfrom(sockfd,text,sizeof(text),0,(struct sockaddr *)&sin,&sinlen))<0){perror("recvfrom");exit(1);}printf("接收操作码:%d,块编号:%hd\n",text[1],ntohs(*(short *)(text+2)));if(text[1] == 5){printf("差错码是:%d,差错信息error:%s\n",ntohs(*(short *)(text+2)),text+4);return ;}else if(text[1] == 4){if(flags == 0){if((fd = open(filename,O_RDONLY))<0){perror("open");exit(1);}flags = 1;printf("文件打开成功:%d\n",fd);}int len = read(fd,text+4,512);if (len < 0) { //检查 read 函数的返回值perror("read");exit(1);}//	printf("%s\n",text+4);if(len == 0){break;}text[1] = 3;*(short *)(text+2) = htons(++num);printf("发送操作码:%d,块编号:%hd\n",text[1],ntohs(*(short *)(text+2)));if(sendto(sockfd,text,len+4,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}}}
}

do_download(下载文件)

void do_download(int sockfd,struct sockaddr_in sin,const char *filename){char text[1024] = "";int text_len;socklen_t sinlen = sizeof(sin);int fd;int flags = 0;int num = 0;ssize_t bytes;text_len = sprintf(text,"%c%c%s%c%s%c",0,1,filename,0,"octet",0);if(sendto(sockfd,text,text_len,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}while(1){if((bytes = recvfrom(sockfd,text,sizeof(text),0,(struct sockaddr *)&sin,&sinlen))<0){perror("recvfrom");exit(1);}printf("操作码:%d,块编号:%hd\n",text[1],ntohs(*(short *)(text+2)));if(text[1] == 5){printf("错误码是:%d,错误信息error:%s\n",ntohs(*(short *)(text+2)),text+4);return;}else if(text[1]==3){if(flags==0){if((fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664))<0){perror("open");exit(1);}flags = 1;}if((num+1 == ntohs(*(short *)(text+2))) && (bytes == 516)){num = ntohs(*(short *)(text+2));if(write(fd,text+4,bytes-4)<0){perror("write");exit(1);}text[1] = 4;if(sendto(sockfd,text,4,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}}else if((num+1 == ntohs(*(short *)(text+2)))&&(bytes<516)){if(write(fd,text+4,bytes-4)<0){perror("write");exit(1);}text[1]=4;if(sendto(sockfd,text,4,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}printf("文件下载完毕\n");return;}}}close(fd);
}

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整代码

#include <myhead.h>
#define SERPORT 69
#define SERIP "192.168.11.1"void do_download(int sockfd,struct sockaddr_in sin,const char *filename);
void do_upload(int sockfd,struct sockaddr_in sin,const char *filename);int main(int argc, const char *argv[])
{//1.创建用于通信的套接字文件描述符int clienfd = socket(AF_INET, SOCK_DGRAM, 0);if (clienfd == -1) {perror("socket");return -1;}//2.填充服务器的地址信息结构体struct sockaddr_in sin = {.sin_family = AF_INET,.sin_port = htons(SERPORT),.sin_addr.s_addr = inet_addr(SERIP)};//3.菜单栏选择int choice;char filename[100];while (1) { //3.菜单栏printf("请选择操作:\n");printf("1.上传文件\n");printf("2.下载文件\n");printf("3.退出\n");scanf("%d", &choice);bzero(filename, sizeof(filename));if (choice == 1) {printf("请输入要上传的文件名:");scanf("%s", filename);do_upload(clienfd, sin, filename);} else if (choice == 2) {printf("请输入要下载的文件名:");scanf("%s", filename);do_download(clienfd, sin, filename);} else if (choice == 3) {break;} else {printf("无效选项,请重新选择。\n");}}close(clienfd);return 0;
}void do_download(int sockfd,struct sockaddr_in sin,const char *filename){char text[1024] = "";int text_len;socklen_t sinlen = sizeof(sin);int fd;int flags = 0;int num = 0;ssize_t bytes;text_len = sprintf(text,"%c%c%s%c%s%c",0,1,filename,0,"octet",0);if(sendto(sockfd,text,text_len,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}while(1){if((bytes = recvfrom(sockfd,text,sizeof(text),0,(struct sockaddr *)&sin,&sinlen))<0){perror("recvfrom");exit(1);}printf("操作码:%d,块编号:%hd\n",text[1],ntohs(*(short *)(text+2)));if(text[1] == 5){printf("错误码是:%d,错误信息error:%s\n",ntohs(*(short *)(text+2)),text+4);return;}else if(text[1]==3){if(flags==0){if((fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664))<0){perror("open");exit(1);}flags = 1;}if((num+1 == ntohs(*(short *)(text+2))) && (bytes == 516)){num = ntohs(*(short *)(text+2));if(write(fd,text+4,bytes-4)<0){perror("write");exit(1);}text[1] = 4;if(sendto(sockfd,text,4,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}}else if((num+1 == ntohs(*(short *)(text+2)))&&(bytes<516)){if(write(fd,text+4,bytes-4)<0){perror("write");exit(1);}text[1]=4;if(sendto(sockfd,text,4,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}printf("文件下载完毕\n");return;}}}close(fd);
}void do_upload(int sockfd,struct sockaddr_in sin,const char *filename){char text[1024] = "";int text_len;socklen_t sinlen = sizeof(sin);int fd;int flags = 0;int num = 0;ssize_t bytes;text_len = sprintf(text,"%c%c%s%c%s%c",0,2,filename,0,"octet",0);if(sendto(sockfd,text,text_len,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}while(1){if((bytes = recvfrom(sockfd,text,sizeof(text),0,(struct sockaddr *)&sin,&sinlen))<0){perror("recvfrom");exit(1);}printf("接收操作码:%d,块编号:%hd\n",text[1],ntohs(*(short *)(text+2)));if(text[1] == 5){printf("差错码是:%d,差错信息error:%s\n",ntohs(*(short *)(text+2)),text+4);return ;}else if(text[1] == 4){if(flags == 0){if((fd = open(filename,O_RDONLY))<0){perror("open");exit(1);}flags = 1;printf("文件打开成功:%d\n",fd);}int len = read(fd,text+4,512);if (len < 0) { //检查 read 函数的返回值perror("read");exit(1);}//	printf("%s\n",text+4);if(len == 0){break;}text[1] = 3;*(short *)(text+2) = htons(++num);printf("发送操作码:%d,块编号:%hd\n",text[1],ntohs(*(short *)(text+2)));if(sendto(sockfd,text,len+4,0,(struct sockaddr *)&sin,sinlen)<0){perror("sendto");exit(1);}}}
}

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

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

相关文章

java开发中间件学习记录(持续更新中~)

1 Redis 2JVM 3 java基础底层 4Mysql 5 spring 6 微服务 7.......(持续更新) One:Redis篇 1:Redis 1.穿透 1.1缓存穿透 1.1.1布隆过滤器 1.2缓存击穿 2&#xff1a;击穿 1.3&#xff1a;缓存雪崩 1.4:双写一致 1.5.持久化&#xff08;RDB,AOF&#xff09; 1.6…

深入浅出Docker

1. Docker引擎 Docker引擎是用来运行和管理容器的核心软件。通常人们会简单的将其指代为Docker或Docker平台。 基于开放容器计划&#xff08;OCI&#xff09;相关的标准要求&#xff0c;Docker引擎采用了模块化的设计原则&#xff0c;其组件是可替换的。 Docker引擎由如下主…

k8s中的存储

目录 一 configmap 1.1 configmap的功能 1.2 configmap的使用场景 1.3 configmap创建方式 1.3.1 字面值创建 1.3.2 通过文件创建 1.3.3 通过目录创建 1.3.4 通过yaml文件创建 1.3.5 configmap的使用方式 1.3.5.1 使用configmap填充环境变量 1.3.5.2 通过数据卷使用c…

YOLOv10改进系列,YOLOv10颈部网络SPPF替换为FocalModulation

摘要 焦点调制网络(简称FocalNets),其中自注意力(SA)完全由焦点调制模块取代,用于在视觉中建模标记交互。焦点调制包括三个组件:(i)焦点情境化,通过一堆深度卷积层实现,从短到长范围编码视觉上下文,(ii)门控聚合,选择性地将上下文聚集到每个查询标记的调制器中…

词嵌入(二):基于上下文窗口的静态词嵌入(从NNLM、CW模型谈到基于层次Softmax、负采样的Word2Vec模型)

文章目录 一、经典神经语言模型&#xff08;A Neural Probabilistic Language Model&#xff09;二、C&W模型 (Collobert and Weston, 2008)2.1 文章背景2.2 模型架构&#xff08;词向量的表示&#xff09;2.2.1 Lookup-Table Layer&#xff08;查找表&#xff09;2.2.2 TD…

基于单片机的风机故障检测装置的设计与实现(论文+源码)

1 系统总体设计方案 通过对风机故障检测装置的设计与实现的需求、可行性进行分析&#xff0c;本设计风机故障检测装置的设计与实现的系统总体架构设计如图2-1所示&#xff0c;系统风机故障检测装置采用STM32F103单片机作为控制器&#xff0c;并通过DS18B20温度传感器、ACS712电…

VMware Fusion虚拟机Mac版 安装Win10系统教程

Mac分享吧 文章目录 Win10安装完成&#xff0c;软件打开效果一、VMware安装Windows10虚拟机1️⃣&#xff1a;准备镜像2️⃣&#xff1a;创建虚拟机3️⃣&#xff1a;虚拟机设置4️⃣&#xff1a;安装虚拟机&#xff08;步骤和Win11安装步骤类似&#xff0c;此处相同步骤处没换…

dll修复工具4DDiG DLL Fixer,解决电脑dll丢失问题

4DDiG DLL Fixer是一款专业的DLL修复工具&#xff0c;旨在解决Windows系统中各种DLL相关问题。该工具能够快速全面地扫描计算机&#xff0c;检测并修复导致程序功能异常的DLL错误。它支持一键式操作&#xff0c;自动扫描、识别和替换缺失或损坏的DLL文件&#xff0c;从而帮助用…

opencv之Canny边缘检测

文章目录 前言1.应用高斯滤波去除图像噪声2.计算梯度3.非极大值抑制4.应用双阈值确定边缘5.Canny函数及使用 前言 Canny边缘检测是一种流行的边缘检测算法&#xff0c;用于检测图像中的边缘。它通过一系列步骤将图像中的像素边缘突出显示出来&#xff0c;主要分为以下几个步骤…

★ C++进阶篇 ★ 多态

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;我将继续和大家一起学习C进阶篇第一章----多态 ~ ❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️ 澄岚主页&#xff1a;椎名澄嵐-CSDN博客 C基础篇专栏&#xff1a;★ C基础篇 ★_椎名澄嵐的博客-CSDN博客 …

数据处理脚手架PyODPS入门体验

本文分享了初次使用PyODPS&#xff08;Python版的Open Data Processing Service&#xff09;的心路历程。作者通过实际案例&#xff0c;深入浅出地探讨了PyODPS相较于传统ODPS SQL在数据处理上的灵活性与便捷性&#xff0c;特别是在处理复杂JSON字段统计与多条件筛选方面展现出…

带你如何使用CICD持续集成与持续交付

目录 一、CICD是什么 1.1 持续集成&#xff08;Continuous Integration&#xff09; 1.2 持续部署&#xff08;Continuous Deployment&#xff09; 1.3 持续交付&#xff08;Continuous Delivery&#xff09; 二、git工具使用 2.1 git简介 2.2 git的工作流程 2.3 部署g…

基于R语言的统计分析基础:使用SQL语句操作数据集

在使用R语言数据分析时&#xff0c;可以融合SQL语言使数据聚集操作更加便利&#xff0c;同时也可以增加对SQL语句的熟悉。借助sqldf、DBI、RSDLite等包&#xff0c;可以在R环境中直接运用SQL语句&#xff0c;轻松实现数据的分组统计、汇总分析&#xff0c;SQL的强大查询能力简化…

腾讯云2024年数字生态大会开发者嘉年华(数据库动手实验)TDSQL-C初体验

在2024年9月5-6日&#xff0c;有幸参加了腾讯云举办的2024年数字生态大会开发者嘉年华。 有幸体验了腾讯的多项黑科技和云计算知识。特别是在“增一行代码”互动展区&#xff0c;体验了腾讯云云计算数据库TDSQL-C技术并进行了动手实验。这些技术充分展示了腾讯在云计算的强大实…

Vite + Electron 时,Electron 渲染空白,静态资源加载错误等问题解决

问题 如果在 electron 里直接引入 vite 打包后的东西&#xff0c;那么有些资源是请求不到的 这是我的引入方式 根据报错&#xff0c;我们来到 vite 打包后的路径看一看 &#xff0c;修改一下 dist 里的文件路径试了一试 修改后的样子&#xff0c;发现是可以的了 原因分析 …

粒子群算法(PSO算法)求解实例---旅行商问题 (TSP)

目录 一、采用PSO求解 (TSP)二、 旅行商问题2.1 实际例子&#xff1a;求解 6 个城市的 TSP2.2 **求解该问题的代码**2.3 代码运行过程截屏2.4 代码运行结果截屏&#xff08;后续和其他算法进行对比&#xff09; 三、 如何修改代码&#xff1f;3.1 减少城市坐标&#xff0c;如下…

Porcupine - 语音关键词唤醒引擎

文章目录 一、关于 Porcupine特点用例尝试一下 语言支持性能 二、Demo1、Python Demo2、iOS DemoBackgroundService DemoForegroundApp Demo 3、网页 Demo3.1 Vanilla JavaScript 和 HTML3.2 Vue Demos 三、SDK - Python 一、关于 Porcupine Porcupine 是一个高度准确和轻量级…

【软件测试】--xswitch将请求代理到测试桩

背景 在做软件测试的过程中&#xff0c;经常会遇见需要后端返回特定的响应数据&#xff0c;这个时候就需要用到测试桩&#xff0c;进行mock测试。 测试工程师在本地模拟后端返回数据时&#xff0c;需要将前端请求数据代理到本地&#xff0c;本文介绍xswitch插件代理请求到flas…

基于环境音频和振动数据的人类活动识别

这篇论文的标题是《Recognition of human activities based on ambient audio and vibration data》&#xff0c;作者是 Marcel Koch 等人&#xff0c;发表在 IEEE Access 期刊上。论文提出了一种基于环境音频和振动数据的分布式多传感器系统&#xff0c;用于识别人类活动。以下…

Anaconda安装并配置Python环境

背景概述 Anaconda&#xff0c;中文大蟒蛇&#xff0c;是一个开源的Anaconda是专注于数据分析的Python发行版本&#xff0c;包含了conda、Python等190多个科学包及其依赖项。 Anaconda就是可以便捷获取包且对包能够进行管理&#xff0c;包括了python和很多常见的软件库和一个…