要怎么做网站推广,深圳最好的网站制作哪家公司好,旅游网站制作视频百度云,响应式大学网站1#xff09;tftp协议概述
简单文件传输协议#xff0c;适用于在网络上进行文件传输的一套标准协议#xff0c;使用UDP传输特点#xff1a; 是应用层协议 基于UDP协议实现 数据传输模式 octet#xff1a;二进制模式#xff08;常用#xff09; mail#xff1a;已经不再…1tftp协议概述
简单文件传输协议适用于在网络上进行文件传输的一套标准协议使用UDP传输特点 是应用层协议 基于UDP协议实现 数据传输模式 octet二进制模式常用 mail已经不再支持
TFTP通信过程总结
服务器在69号端口等待客户端的请求 服务器若批准此请求则使用 临时端口 与客户端进行通信。 每个数据包的编号都有变化从1开始 每个数据包都要得到ACK的确认如果出现超时则需要重新发送最后的数据包或ACK包 数据长度以512Byte传输的小于512Byte的数据意味着数据传输结束。
3tftp协议分析 代码
#include head.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.h
#include sys/socket.h
#include arpa/inet.h
#include netinet.h#define PORT 69
#define IP 10.102.145.165
int main(int argc, const char *argv[])
{//创建报式套接字int cfd socket(AF_INET,SOCK_DGRAM,0);if(cfd 0){ERRO_MES(socket);return -1;}printf(cfd %d\n,cfd);//填充服务器的地址信息结构体给sendto函数使用//发送给谁就填谁的地址信息struct sockaddr_in sin;sin.sin_family AF_INET; //必须填AF_INETsin.sin_port htons(PORT); //端口号服务器绑定的端口号sin.sin_addr.s_addr inet_addr(IP); //IP服务器绑定的IPchar choose 0;while(1){printf(*********************\n);printf(********1. 下载******\n);printf(********2. 上传******\n);printf(********3. 退出******\n);printf(*********************\n);printf(请输入 );choose getchar();while(getchar() ! 10); //循环获取字符串直到遇到/n结束循环switch(choose){case 1:do_download(cfd,sin);break;case 2:do_upload;break;case 3:goto END;break;default:printf(输入错误请重新输入\n);}}
END://关闭文件描述符close(cfd);return 0;
}
int do_download(int cfd,struct sockaddr sin)
{//发送下载请求char buf[516] ;char name[20] ;printf(请输入要下载的文件名 );scanf(%s,name);while(getchar()!10);unsigned short *p1 (unsigned short*)buf;*p1 htons(1);char* p2 buf2;strcpy(p2, name);char *p p2strlen(p2);*p3 0;char* p4 p31;strcpy(p4,octet);int size 2strlen(p2)1strlen(p4)1;if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)sin,sizeof(sin)) 0){ERRO_MES(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){ERRO_MES(recvfrom);return -1;}//由于操作码占两个字节且是大端字节序//所以低字节存储在高地址高字节存储在低地址//有效操作码存储在高地址上即buf[1]的位置if(3 buf[1]){//判断服务器返回的数据包的块编号与本地记录的块编号是否一致if(*(unsigned short*)(buf2) htons(num1)){num; //更新本地记录的块编号if(-1 fd){fd open(name,O_WRONLY | O_CREAT | O_TRUNC,0664);if(fd 0){ERRO_MES(open);return -1;}}//将数据写入到文件中if(write(fd,buf4,res-4) 0){ERRO_MES(write);close(fd);return -1;}//发送ACK发送到临时端口buf[1] 4;if(sendto(cfd,buf,4,0,(struct sockaddr*)sin,sizeof(sin)) 0){ERRO_MES(sendto);return -1;}//若接收到的数据小于512跳出循环结束下载if(res-4 512){printf(%s 文件下载完毕\n,name);break;}}}else if(5 buf[1]) //错误包{printf(错误%d %s\n,ntohs(*(short*)(buf2)),buf4);close(fd);return -1;}}close(fd);return 0;
}