当前位置: 首页 > 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.dtcms.com/a/337146.html

相关文章:

  • 后端通用基础代码
  • 电源电路介绍
  • OpenTelemetry、Jaeger 与 Zipkin:分布式链路追踪方案对比与实践
  • 窗口看门狗(WWDG)
  • 网络基础——协议认识
  • Linux权限的学习
  • 抽象类与接口的区别
  • 【C语言篇】操作符详解
  • Ubuntu下无法在huggingface下载指定模型的解决方法
  • Read Frog:一款开源AI浏览器语言学习扩展
  • 如何解决IDEA/Datagrip无法连接数据库的问题:解决方法为添加参数-Djava.net.preferIPv4Stack=true
  • Java原子类详解
  • 并发编程原理与实战(二十四)Java并发基石LockSupport park/unpark机制全解析
  • 车e估牵头正式启动乘用车金融价值评估师编制
  • AI出题人给出的Java后端面经(十八)(日更)
  • Java基础八股复习3 jvm-内存结构
  • 数据仓库理论
  • 具身智能2硬件架构(人形机器人)摘自Openloong社区
  • Vue3 中使用 Element Plus 完整指南
  • 博客项目 Spring + Redis + Mysql
  • 利用DeepSeek辅助WPS电子表格ET格式分析
  • 代码随想录算法训练营四十五天|图论part03
  • flask——4:请求与响应
  • 机器学习(决策树)
  • pytest的前置与后置
  • 决策树:机器学习中的直观分类与回归工具
  • CPTS---Active 复现
  • Python netifaces 库详解:跨平台网络接口与 IP 地址管理
  • Alma Linux 8 中解决掉 Failed to set locale, defaulting to C.UTF-8
  • vue3入门-v-model、ref和reactive讲解