网站开发设计工具,陕西网站建设排名,wordpress媒体打不开,今天北京发生的重大新闻1#xff09;tftp协议概述 简单文件传输协议#xff0c;适用于在网络上进行文件传输的一套标准协议#xff0c;使用UDP传输 特点#xff1a; 是应用层协议 基于UDP协议实现 数据传输模式 octet#xff1a;二进制模式#xff08;常用#xff09; mail#xff1a;已经不再…1tftp协议概述 简单文件传输协议适用于在网络上进行文件传输的一套标准协议使用UDP传输 特点 是应用层协议 基于UDP协议实现 数据传输模式 octet二进制模式常用 mail已经不再支持 2tftp下载模型 TFTP通信过程总结 服务器在69号端口等待客户端的请求服务器若批准此请求则使用 临时端口 与客户端进行通信。每个数据包的编号都有变化从1开始每个数据包都要得到ACK的确认如果出现超时则需要重新发送最后的数据包或ACK包数据长度以512Byte传输的小于512Byte的数据意味着数据传输结束。 代码实现
main.c
#includetftp.hint main(int argc, const char *argv[])
{int cmd 0;//用来标记操作char filename[20] ;//存放文件名int cfd socket(AF_INET,SOCK_DGRAM,0);//创建套接字文件if(cfd -1){perror(socket error);return -1;}while(1){menu();printf(请输入要执行的操作:);scanf(%d,cmd);switch(cmd){case 1:printf(请输入文件名:);scanf(%s,filename);download(cfd,filename);break;case 2:printf(请输入文件名:);scanf(%s,filename);upload(cfd,filename);break;case 3:printf(退出\n);goto END;break;default:printf(输入错误\n);break;}}
END://关闭文件描述符close(cfd);return 0;
}
tftp.c
#includetftp.h
//菜单
void menu()
{printf(-------------------------\n);printf(--------1.下载文件--------\n);printf(--------2.上传文件--------\n);printf(--------3.退出------------\n);printf(-------------------------\n);
}//上传
int upload(int cfd , char *filename)
{char buf[N] ;short *p1 (short*)buf;*p1 htons(2);//设置操作码为2表示上传char *p2 buf 2;//文件名的起始位置strcpy(p2,filename);char *p4 p2 strlen(p2) 1;//模式的起始位置strcpy(p4,octet);int size 2 strlen(p2) strlen(p4) 2;//计算请求包的总长度//打开本地文件int fd open(filename,O_RDONLY);if(fd -1){perror(open error);return -1;}//绑定服务器地址信息结构体struct sockaddr_in sin;sin.sin_family AF_INET;sin.sin_port htons(SER_PORT);sin.sin_addr.s_addr inet_addr(SER_IP);socklen_t len sizeof(sin);//给服务段发送请求if(sendto(cfd,buf,size,0,(struct sockaddr*)sin,sizeof(sin)) -1){perror(sendto error);return -1;} short flag 1;//设置标示位//收发数据while(1){//清空数据bzero(buf,sizeof(buf));if(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)sin,len)-1){perror(recvfrom error);return -1;}//将ack改造成为数据包if(buf[1] 4 || flag buf[2]){int res read(fd,buf4,sizeof(buf)-4);//从buf的5个开始放数据读取buf-4个数据if(res 0){perror(read error);return -1;}if(res 0){printf(文件发送完毕\n);return -1;}buf[1]3;buf[3] flag;if(sendto(cfd,buf,res4,0,(struct sockaddr*)sin,sizeof(sin)) -1){perror(sendto error);return -1;} flag;}if(buf[1] 5){printf(接收错误\n);break;}}
}//下载
int download(int cfd ,char *filename)
{char buf[N] ;short *p1 (short*)buf;*p1 htons(1);//设置操作码为1表示下载char *p2 buf 2;//文件名的起始位置strcpy(p2,filename);char *p4 p2 strlen(p2) 1;//模式的起始位置strcpy(p4,octet);int size 2 strlen(p2) strlen(p4) 2;//计算请求包的总长度//创建本地文件int fd open(filename,O_CREAT|O_WRONLY|O_TRUNC,0644);if(fd -1){perror(open error);return -1;}//绑定服务器地址信息结构体struct sockaddr_in sin;sin.sin_family AF_INET;sin.sin_port htons(SER_PORT);sin.sin_addr.s_addr inet_addr(SER_IP);socklen_t len sizeof(sin);//给服务段发送请求if(sendto(cfd,buf,size,0,(struct sockaddr*)sin,sizeof(sin)) -1){perror(sendto error);return -1;} short flag 1;//设置标示位while(1){//清空bzero(buf,sizeof(buf));//获取服务器发来的包int res recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)sin,len);if(res -1){perror(recvfrom error);return -1;}//判断是否是数据包if(buf[1] 3 flag ntohs(*(short*)(buf2))){//将数据写入文件中if(write(fd,buf4,N-4)-1){perror(write error);return -1;}//返回ackbuf[1] 4; if(sendto(cfd,buf,4,0,(struct sockaddr*)sin,sizeof(sin))-1){perror(sendto error);return -1;}flag;//确保和需要的块编号一致}//判断是否是错误包if(buf[1] 5){printf(文件发送错误\n);}//判断是否发送完毕if(res 516){printf(文件接收完毕\n);return -1;}}
}tftp.h
#ifndef TFTP_H
#define TFTP_H
#define SER_PORT 69
#define SER_IP 192.168.1.4
#define N 516
#includemyhead.h
//菜单
void menu();//上传
int upload(int cfd , char *filename);//下载
int download(int cfd ,char *filename);#endif
效果展示