作业:基于udp的tftp文件传输实例
#include <head.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>#define PORT 69 //服务器绑定的端口号
#define IP "192.168.1.107" //服务器的IP地址int do_download(int cfd,struct sockaddr_in sin);
int do_upload(int cfd, struct sockaddr_in sin);int main(int argc, const char *argv[])
{//创建报式套接字int cfd = socket(AF_INET, SOCK_DGRAM, 0);if(cfd < 0){ERR_MSG("socket");return -1;}printf("cfd = %d\n",cfd);//绑定客户端的地址信息结构体到套接字上--->非必须绑定//若不绑定,则操作系统会给客户端绑定运行主机的IP和随机的端口号//填充要连接的服务器地址信息结构体,真实的地址信息结构体根据地址族制定//要发给谁,就填谁的地址信息//AF_INET : man 7 ipstruct sockaddr_in sin;socklen_t addrlen=sizeof(sin);sin.sin_family = AF_INET; //必须填AF_INETsin.sin_port = htons(PORT); //端口号:服务器绑定的端口号sin.sin_addr.s_addr = inet_addr(IP); //服务器绑定的IPchar choose =0;while(1){printf("*******************\n");printf("******1. 下载******\n");printf("******2. 上传******\n");printf("******3. 退出******\n");printf("*******************\n");printf("*******************\n");printf("请输入>>> ");choose = getchar();while(getchar() != 10); //循环获取字符,直到遇到\n结束循环switch(choose){case '1':do_download(cfd,sin);break;case '2':do_upload(cfd,sin);break;case '3':goto END;break;default:printf("输入错误!请重新输入\n");}}
END://关闭文件描述符close(cfd);return 0;
}int do_download(int cfd, struct sockaddr_in sin)
{//组包准备发送下载请求char buf[516]="";char name[20]="";printf("请输入要下载的文件名>>> ");scanf("%s",name);while(getchar()!=10);unsigned short *p1=(short*)buf; //操作码*p1=htons(1);char *p2=buf+2; //文件名strcpy(p2,name);char *p3=p2+strlen(p2); //第一个0 *p3=0;char *p4=p3+1; //模式 strcpy(p4,"octet");size_t size=2+strlen(p2)+1+strlen(p4)+1; //操作码+文件名+0+模式+0//发送下载请求if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}//创建下载文件并清空int fd = -1; //必须初始化成一个无效的文件描述符socklen_t addrlen = sizeof(sin);ssize_t res = 0;unsigned short num = 0; //记录本地的块编号//发送下载请求while(1){//接收数据bzero(buf,sizeof(buf));res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);if(res < 0){ERR_MSG("recvfrom");return -1;}if(3 == buf[1]) //数据包{//判断服务器返回的数据包的块编号与本地记录的块编号是否一致if(*(unsigned short*)(buf+2) == htons((num+1))){num++; //更新本地记录的块编号if(-1 == fd){fd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fd < 0){perror("open");return -1;}}//将数据写到文件中if(write(fd,buf+4,res-4) < 0 ){perror("write");return -1;}//发送ACKbuf[1] = 4;//*p1=htons(4);if(sendto(cfd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}//若接收到的数据小于512跳出循环,结束下载if(res-4 < 512){printf("%s 文件下载完毕\n",name);break;}}}else if(5 == buf[1]) //错误包{printf("错误: %d %s\n",ntohs(*(short*)(buf+2)),buf+4);close(fd);return -1;}}close(fd);return 0;
}int do_upload(int cfd, struct sockaddr_in sin)
{//组包准备发送上传请求char buf[516]="";char name[20]="";printf("请输入要上传的文件名>>> ");scanf("%s",name);while(getchar()!=10);int fd = open(name,O_RDONLY);if(fd < 0){if( errno == ENOENT){printf(">>>文件不存在,请重新输入<<<\n");return -2;}else{ERR_MSG("open");return -1;}}//组包准备发送上传请求unsigned short *p1=(short*)buf; //操作码*p1=htons(2);char *p2=buf+2; //文件名strcpy(p2,name);char *p3=p2+strlen(p2); //第一个0 *p3=0;char *p4=p3+1; //模式 strcpy(p4,"octet");size_t size=2+strlen(p2)+1+strlen(p4)+1; //操作码+文件名+0+模式+0//发送上传请求if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}//循环接收发送数据包ssize_t res;unsigned short num = 0;socklen_t addrlen = sizeof(sin);while(1){//将数据从文件中读取到buf中bzero(buf,sizeof(buf));res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen);if(res < 0){ERR_MSG("recvfrom");return -1;}//操作码的范围是1-5,因为是网络字节序//所以有效操作码存储在高位,即buf[1]的位置//printf("buf[1] = %d\n",buf[1]); //4 服务器返回应答包if(4 == buf[1]) //数据包{//判断当前数据包的编号是否等于应答包的编号//防止数据包在传送过程丢包或重复收包if(num == ntohs(*(unsigned short*)(buf+2))){//修改操作码为数据包buf[1] = 3;//填充块编号num++;*(unsigned short*)(buf+2) = htons(num);//读取数据res = read(fd,buf+4,sizeof(buf)-4);if(res < 0){ERR_MSG("read");return -1;}else if(0 == res){printf("%s 文件上传完毕!\n",name);break;}//发送数据包//发送的数据包大小为,读取到的字节数res+操作码2byte+块编号2bytesif(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}}else{printf("文件上传失败,请检查网络环境\n");break;}}else if(5 == buf[1]) //错误包{printf("错误: %d %s\n",ntohs(*(short*)(buf+2)),buf+4);close(fd);return -1;}}close(fd);return 0;
}

导图:

面试题:
IP地址:网络中主机的标识符
TCP服务端通信流程:创建套接字,然后绑定服务器地址,然后开启被动监听,然后就是与客户端的数据收发,最后关闭套接字。
相关文章:
作业:基于udp的tftp文件传输实例
#include <head.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h>#define PORT 69 //服务器绑定的端口号 #define IP "192.168.1.107" //服务器的IP地址int do_download(i…...
【数据结构和算法】-贪心算法
贪心算法(又称贪婪算法)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。贪心算法在有最优子结构的问题中尤为有效,它通过将问题分解为一系列…...
路由器里如何设置端口映射?
在互联网时代,我们经常需要将内部网络的服务暴露到公网以便其他人访问。直接将内部网络暴露在公网上存在一定的安全风险。为了解决这个问题,我们可以利用路由器里设置端口映射来实现将特定端口的访问请求转发到内部网络的特定设备上。 端口映射的原理 端…...
M3C芯片——支持工业级HMI应用,集成2D加速、4路串口及2路CAN
M3C芯片是一款基于 RISC-V 的高性能、国产自主、工业级高清显示与智能控制 MCU,配备强大的 2D 图形加速处理器、PNG/JPEG 解码引擎、丰富的接口,支持工业宽温,具有高可靠性、高开放性,可广泛应用于工业自动化控制、HMI人机交互、 …...
如何做时间管理?
前言 本篇是最近学习工作提效系列课程的第一篇,如何做时间管理?关于时间管理的内容老生常谈了,我自己之前也分享过针对时间管理的一些思考,比如 近期对「时间管理」的一些思考, 还有高效能人士的七个习惯的分享【读书…...
三级数据库技术考点(详解!!)
1、 答疑:【解析】分布式数据库系统按不同层次提供的分布透明性有:分片透明性;②位置透明性;③局部映像透明性,位置透明性是指数据分片的分配位置对用户是透明的,用户编写程序时只需 要考虑数据分片情况,不需要了解各分片在各个场地的分配情…...
【技术栈】Redis 企业级解决方案
SueWakeup 个人主页:SueWakeup 系列专栏:学习技术栈 个性签名&…...
(一)Linux+Windows下安装ffmpeg
一丶前言 FFmpeg是一个开源的音视频处理工具集,由多个命令行工具组成。它可以在跨平台的环境中处理、转换、编辑和流媒体处理音视频文件。 FFmpeg支持多种常见的音视频格式和编解码器,可以对音视频文件进行编码、解码、转码、剪辑、合并等操作。它具有广…...
docker的部署与安装以及部署一个docker(容器)应用及docker容器常出现的问题
docker 架构图 一、docker的部署与安装 1、在 CentOS 上安装 Docker 移除旧版本(如果有的话):sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-…...
harmonyOS简介及背景
harmonyOS的场景模式18n: 1(入口手机)8(电脑、VR、手环、iPad、智慧屏、)–wifi—n(车载、智能家居等所有)harmonyOS不需要考虑软硬件的差异,是一个兼容N种的超级终端harmonyOS干了两件事: (1&a…...
最新,955神仙公司名单(非外企)
955 神仙公司名单(非外企) 往常爆料最多的 955 神仙公司名单通常都是集中在一线城市的外企。 例如下面这张最为流行的名单图: 最近牛客网上有同学整理出了非外企的版本,其中不乏一些耳熟能详的互联网产品。 随手把名单分享给大家。…...
牛客周赛 Round 37 C.红魔馆的馆主
非常恶心的诈骗,手玩了半小时,发现了一堆规律,比如是11的倍数的偶数数位和奇数数位要相等 还搞上了逆元,是5的倍数必须0 or 5结尾,是9的倍数必须数位之和是9的倍数结果做不出来 然后不是构造是纯纯的暴搜 直接暴力看…...
AWS监控,AWS 性能监控工具
监控云部署的性能是 IT 环境正常运行的内在条件。AWS 云是一个架构良好的框架,管理员可以使用专用的AWS 性能监控工具增强服务的功能。执行AWS监视是为了跟踪在AWS环境中积极运行的应用程序工作负载和资源。AWS监视器跟踪各种AWS云指标,以帮助提高在其上…...
PHP姓名快速匿名化工具(重组脱敏)
PHP姓名重组工具(脱敏/匿名化工具) 将excel数据姓名列粘贴提交,得到随机姓随机中间字随机尾字的重组姓名 那些年自用瞎搞的代码,今日整理成网页交提交得到结果的交互功能分享。 <?php //PHP姓名重组工具(脱敏/匿名化工具) //将excel数据姓名列粘贴…...
JAVA后端调用OpenAI接口 实现打字机效果(SSE)
SSE SSE(Server-Sent Events,服务器发送事件)是一种基于HTTP协议的通信技术,它允许服务器持续地将数据推送给客户端,而无需客户端发起请求。这种通信方式通常用于实时性要求较高的场景,如实时更新、通知、或…...
超店建站携手太洋物产,共建跨境生意增长解决方案
2024年3月21日,至真科技旗下的超店建站与太洋物产在出海业务上达成了合作意向,标志着双方共同构建海外版图的合作正式启动。此次合作充分彰显了超店建站在海外业务方面的卓越技术能力和丰富经验,赢得了太洋物产的高度认可。 当天,…...
提高企业员工生产力的办法
在现代商业环境中,提高企业员工生产力是企业持续发展的关键因素之一。员工生产力的提升不仅有助于企业提高运营效率,还能增强企业的市场竞争力。那么,如何有效地提高企业员工生产力呢?本文将就此问题进行探讨。 一、引入先进技术软…...
XML Data – Semi-Structured Data XML 数据 - 半结构化数据
Outline • Structured, Semistructured, and Unstructured Data • XML Hierarchical (Tree) Data Model • Extracting XML Documents from Relational Databases • XML Documents, DTD, and XML Schema • XML Languages 结构化、半结构化和非结构化数据 - XML 层次&#x…...
Python自动化之如何利用allure生成测试报告
Allure测试报告框架帮助你轻松实现”高大上”报告展示。本文通过示例演示如何从0到1集成Allure测试框架。重点展示了如何将Allure集成到已有的自动化测试工程中、以及如何实现报表的优化展示。Allure非常强大,支持多种语言多种测试框架,无论是Java/Pytho…...
【晴问算法】入门篇—贪心算法—区间不相交问题
题目描述 给定n个开区间,从中选择尽可能多的开区间,使得这些开区间两两没有交集。 输入描述 输出描述 输出一个整数,表示最多选择的开区间个数。 样例1输入 4 1 3 2 4 3 5 6 7 输出 3 解释 最多选择(1,3)、(3,5)、(6,7)三个区间,它…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
32位寻址与64位寻址
32位寻址与64位寻址 32位寻址是什么? 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元(地址),其核心含义与能力如下: 1. 核心定义 地址位宽:CPU或内存控制器用32位…...
MeshGPT 笔记
[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...
数据挖掘是什么?数据挖掘技术有哪些?
目录 一、数据挖掘是什么 二、常见的数据挖掘技术 1. 关联规则挖掘 2. 分类算法 3. 聚类分析 4. 回归分析 三、数据挖掘的应用领域 1. 商业领域 2. 医疗领域 3. 金融领域 4. 其他领域 四、数据挖掘面临的挑战和未来趋势 1. 面临的挑战 2. 未来趋势 五、总结 数据…...
