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

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.lryc.cn/news/625237.html

相关文章:

  • Kafka文件存储机制
  • LeetCode100 -- Day1
  • LeetCode 每日一题 2025/8/11-2025/8/17
  • STM32学习笔记14-I2C硬件控制
  • 嵌入式 C++ 语言编程规范文档个人学习版(参考《Google C++ 编码规范中文版》)
  • 朝花夕拾(七)--------从混淆矩阵到分类报告全面解析​
  • 远程访问公司内网电脑怎么操作?3个简单通用的跨网异地连接管理计算机方法
  • 安全基础DAY6-服务器安全检测和防御技术
  • 超级云平台:重构数字生态的“超级连接器“
  • 2025年- H98-Lc206--51.N皇后(回溯)--Java版
  • Hadoop - 1:Hadoop 技术解析;Hadoop是什么;Hadoop优势;Hadoop组成;HDFS、YARN、MapReduce 三者关系
  • <数据集>遥感飞机识别数据集<目标检测>
  • Ubuntu下无法在huggingface下载指定模型的解决方法
  • FreeRTOS学习笔记(二)
  • MySQL的多版本并发控制(MVCC):
  • Windows系统上使用GIT
  • 基于JS实现的中国象棋AI系统:多模块协同决策与分析
  • 【C语言16天强化训练】从基础入门到进阶:Day 2
  • 计算机大数据毕业设计推荐:基于Hadoop+Spark的食物口味差异分析可视化系统【源码+文档+调试】
  • 数据转换细节揭秘:ETL如何精准映射复杂业务逻辑
  • 深入解析StatefulSet与K8s服务管理
  • 力扣 hot100 Day77
  • LeetCode:无重复字符的最长子串
  • 08.常见文本处理工具
  • vue从入门到精通:轻松搭建第一个vue项目
  • Gemini CLI 系统配置小结
  • SpringBoot3整合OpenAPI3(Swagger3)完整指南
  • EasyExcel篇
  • PDF处理控件Aspose.PDF教程:将 PNG 合并为 PDF
  • 牛客周赛 Round 105(小苯的xor构造/小苯的权值计算/小苯的01矩阵构造/小苯的重排构造/小苯的xor图/小苯的前缀gcd构造)