当前位置: 首页 > web >正文

8.18网络编程——基于UDP的TFTP文件传输客户端

文章目录

  • 一、思维导图
  • 二、基于UDP的TFTP文件传输
    • 1、myhead.h
    • 2、客户端代码
  • 三、牛客网刷题

一、思维导图

在这里插入图片描述

二、基于UDP的TFTP文件传输

1、myhead.h

#ifndef __MYHEAD_H__
#define __MYHEAD_H__#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>#define ERR_MSG(msg) do{perror(msg);printf("%d\n",__LINE__);return -1;}while(0)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <sys/wait.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/msg.h>
#endif

2、客户端代码

#include<myhead.h>#define SER_IP "192.168.109.125"       //服务器ip地址
#define SER_PORT 69                  //服务器端口号
#define CLI_IP  "192.168.117.113"      //客户端ip地址
#define CLI_PORT 9999                  //客户端端口号
void dowload(int cfd,struct sockaddr_in sin,socklen_t addrlen)
{//定义协议包数组char msgBuf[516] = ""; //提示并输入文件名char fileName[21] = "";           //记录文件名printf("请输入您要下载的文件名:");scanf("%s", fileName);//封装请求协议short *p1 =(short *)msgBuf;           //封装请求*p1 = htons(1);               //表示下载请求包char *p2 = msgBuf + 2;         //文件名部分strcpy(p2, fileName);char *p4 = p2 + strlen(p2) + 1;         //传输模式strcpy(p4, "octet");int msgLen = 2 + strlen(p2) + strlen(p4) +2;    //请求包的长度//将消息发送给服务器sendto(cfd, msgBuf, msgLen, 0, (struct sockaddr*)&sin, sizeof(sin));ssize_t len;//以只写的形式打开一个文件,文件名为  fileNameumask(0);int fd=open(fileName,O_WRONLY | O_CREAT | O_TRUNC,0664);while(1){//接收服务器发来的数据包//判断是错误包还是数据包len=recvfrom(cfd,msgBuf,516,0,(struct sockaddr*)&sin,&addrlen);//如果是数据包,读取数据包4字节之后的数据//如果数据包长度为512,则将消息写入文件后//向服务器回复一个应打包//如果数据包长度小于512,则接收完数据写入文件后,回复一个应打包后,就可以//结束循环了if(msgBuf[1]==3){	write(fd,msgBuf+4,len-4);msgBuf[1]=4;sendto(cfd, msgBuf, 4, 0, (struct sockaddr*)&sin, sizeof(sin));if(len-4<512){break;}}else if(msgBuf[1]==5){if(msgBuf[3]==1){remove(fileName);}printf("%s\n",msgBuf+4);break;}}
}
void updoading(int cfd,struct sockaddr_in sin,socklen_t addrlen)
{//定义协议包数组char msgBuf[516] = ""; //提示并输入文件名char fileName[21] = "";           //记录文件名printf("请输入您要上传的文件名:");scanf("%s", fileName);	//以只读的形式打开一个文件,文件名为  fileNameint fd=open(fileName,O_RDONLY);if(fd==-1){perror("open error");return;}//封装请求协议short *p1 =(short *)msgBuf;           //封装请求*p1 = htons(2);               //表示上传请求包char *p2 = msgBuf + 2;         //文件名部分strcpy(p2, fileName);char *p4 = p2 + strlen(p2) + 1;         //传输模式strcpy(p4, "octet");int msgLen = 2 + strlen(p2) + strlen(p4) +2;    //请求包的长度//将消息发送给服务器sendto(cfd, msgBuf, msgLen, 0, (struct sockaddr*)&sin, sizeof(sin));int len;while(1){//接收服务器发来的ACK//判断是错误包还是ACKrecvfrom(cfd,msgBuf,4,0,(struct sockaddr*)&sin,&addrlen);//如果是ACK,写入数据在数据包4字节之后//如果数据包长度为512,则将消息写入文件后,向服务器回复一个数据包//如果数据包长度小于512,则发送数据包后,结束循环if(msgBuf[1]==4){	len=read(fd,msgBuf+4,512);printf("len=%d\n",len);msgBuf[1]=3;sendto(cfd, msgBuf,len+4, 0, (struct sockaddr*)&sin, sizeof(sin));if(len<512){break;}}else if(msgBuf[1]==5){printf("%s\n",msgBuf+4);break;}}}int main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符int cfd = socket(AF_INET, SOCK_DGRAM, 0);if(-1 == cfd){perror("socket error");return -1;}printf("socket success  cfd = %d\n", cfd);           //3//2、绑定ip地址和端口号(可选)//2.1 填充客户端地址信息结构体struct sockaddr_in cin;cin.sin_family = AF_INET;                //通信域cin.sin_port = htons(CLI_PORT);          //客户端端口号cin.sin_addr.s_addr = inet_addr(CLI_IP);  //客户端ip地址//2.2 进行绑定工作if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1){perror("bind error");return -1;}printf("bind  success\n");//3、数据收发//封装服务器的地址信息结构体struct sockaddr_in sin;             //服务器地址信息结构体sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);         //服务器端口号sin.sin_addr.s_addr = inet_addr(SER_IP);  //服务器ip地址socklen_t addrlen = sizeof(sin);          //地址信息结构体的大小int num;while(1){printf("1.下载\n");printf("2.上传\n");printf("3.退出\n");scanf("%d",&num);switch(num){case 1:dowload(cfd,sin,addrlen);break;case 2:updoading(cfd,sin,addrlen);break;case 3:break;}if(num==3)break;}//4、关闭客户端close(cfd);return 0;
}

三、牛客网刷题

在这里插入图片描述

http://www.xdnf.cn/news/18294.html

相关文章:

  • 力扣32:最长有效括号
  • 如何解决机器翻译的“幻觉“问题(Hallucination)?
  • 博客项目 Spring + Redis + Mysql
  • 深度研究系统、方法与应用的综述
  • android 实现表格效果
  • 接口文档——前后端分离开发模式下的“契约书“
  • Java原子类详解
  • MySQL的多版本并发控制(MVCC):
  • illustrator插件大全 免费插件介绍 Ai设计插件集合 (4)
  • LeetCode 每日一题 2025/8/11-2025/8/17
  • Windows 安装使用 MySQL
  • C++架构设计原则
  • 监督学习(Supervised Learning)和 无监督学习(Unsupervised Learning)详解
  • MySQL新手教学
  • 之前说的要写的TCP高性能服务器,今天来了
  • Elasticsearch全文检索中文分词:IK分词器详解与Docker环境集成
  • 用 Python 实现一个“小型 ReAct 智能体”:思维链 + 工具调用 + 环境交互
  • 如何使用 React 101 的 Highcharts 包装器
  • Pomian语言处理器 研发笔记(一):使用C++的正则表达式构建词法分析器
  • 视频讲解:CatBoost、梯度提升 (XGBoost、LightGBM)对心理健康数据、交通流量及股票价格预测研究
  • 从数据汇总到高级分析,SQL 查询进阶实战(下篇)—— 分组、子查询与窗口函数全攻略
  • 8.18 表达式树|浮点数绝对值
  • 基于Flink CDC实现联系人与标签数据实时同步至ES的实践
  • Ps 2025 图像编辑 Photoshop(Mac中文)
  • 【避坑指南】初始化与更新共享数据赋值的一致性问题
  • 【数模国奖冲刺】备赛过程中的常见问题
  • Linux 服务:RAID 级别解析与 mdadm 工具实操指南
  • SWMM排水管网水力、水质建模及在海绵与水环境中的应用技术-模拟降雨和污染物质经过地面、排水管网、蓄水和处理
  • 计算机大数据毕业设计推荐:基于Hadoop+Spark的食物口味差异分析可视化系统【源码+文档+调试】
  • 第一阶段C#基础-13:索引器,接口,泛型