TFTP
协议
最初用于引导无盘系统,被设计用来传输小文件
- TFTP基于UDP协议。
- TFTP的编程思想 和 UDP一样
- TFTP:简单文件传送协
特点:
- 基于UDP协议实现
- 不进行用户有效性认证
数据传输模式:
- octet:二进制模式
- netascii:文本模式
- mail:已经不再支持
TFTP通信过程总结(无选项)
- 服务器在69号端口等待客户端的请求
- 服务器若批准此请求,则使用临时端口与客户端进行通信
- 每个数据包的编号都有变化(从1开始)、逐次递增
- 每个数据包都要得到ACK的确认如果出现超时,则需要重新发送最后的包(数据或ACK)
- 数据的长度以512Byte传输
小于512Byte的数据意味着传输结束
TFTP
协议报文分析
前两个字节为操作码
注意:
- 以上的0代表的是’\0’
- 不同的差错码对应不同的错误信息
TFTP
带选项
tsize选项
- 当读操作时,tsize选项的参数必须为“0”,服务器会返回待读取的文件的大小
- 当写操作时,tsize选项参数应为待写入文件的大小,服务器会回显该选项
blksize选项
- 修改传输文件时使用的数据块的大小(范围:8~65464)
timeout选项
代码示例
此处为 客服端,服务器端可以配合此软件测试。
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
using namespace std;
int main(int argc,char *argv[])
{
if(argc != 2){
perror("参数过少");
exit(1);
}
int sockfd;
if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1){
perror("socket err");
exit(1);
}
char cmd[128] = "";
int len = sprintf(cmd,"%c%c%s%c%s%c",0x00,0x01,argv[1],0,"octet",0);
struct sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("192.168.217.1");
servAddr.sin_port = htons(69);
socklen_t servLen = sizeof(servAddr);
sendto(sockfd,cmd,len,0,(struct sockaddr*)&servAddr,servLen);
int fd = open("/home/hehe.mp4",O_CREAT|O_RDWR|O_TRUNC,S_IRWXU);
if(fd == -1){
perror("open error");
exit(1);
}
unsigned char buf[1024] = "";
memset(buf,0,sizeof (buf));
struct sockaddr_in clieAddr;
socklen_t clieLen = sizeof(clieAddr);
unsigned short num = 1;
while (1) {
int recvLen = recvfrom(sockfd,buf,sizeof (buf),0,(struct sockaddr*)&clieAddr,&clieLen);
if(buf[1] == 0x03){
if(num == ntohs(*(unsigned short*)(buf+2))){
write(fd,buf+4,recvLen-4);
++num;
cout << ntohs(*(unsigned short*)(buf+2)) << endl;
}
buf[1] = 0x04;
sendto(sockfd,buf,4,0,(struct sockaddr*)&clieAddr,clieLen);
if(recvLen < 512){
break;
}
}
}
close(fd);
close(sockfd);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)