TFTP协议(1)TFTP协议介绍(包括:TFTP的五种报文/报文字段扩展/TFTP的流量控制,差错控制/UDP sendto,recvfrom接口)


TFTP协议(2)TFTP源码实现
https://blog.csdn.net/lqy971966/article/details/121819432
FTP协议和TFTP协议的区别
https://blog.csdn.net/lqy971966/article/details/90934673

1. TFTP协议

1.1 TFTP 背景

TFTP(简单文件传输协议)

由于TFTP最初是设计用于系统引导进程,它不提供用户名和口令。

常用于无盘工作站或路由器从别的主机上获取引导配置文件,由于TFTP报文比较小,能够迅速复制这些文件。

1.2 TFTP协议介绍:

<1>TFTP客户机/服务器模式的文件传输协议
<2>TFTP适用于客户端和服务器之间不需要复杂交互的环境
<3>TFTP承载在UDP之上,端口号69
<4>TFTP仅提供简单的文件传输功能(上传、下载)
<5>TFTP协议传输由客户端发起的

1.3 特点:

1、简单
2、占用资源小,由于TFTP报文比较小,能够迅速复制这些文件
3、适合传递小文件
4、适合在局域网进行传递
5、端口号为69
6、基于UDP实现
7. TFTP是一种类似于停止等待协议
   TFTP服务器只有收到客户端的确认报文ACK后才会向客户端接着发送新的数据。
8. 服务器向客户端发送数据的过程中,每次都是发送512B的数据,
   如果客户进程收到某个DATA报文中数据部分的长度小于512B,说明这是收到的最后一个报文;
   如果待发送的数据的总长度正好是512的整数倍,这就意味着最后一个数据报的长度正好为512B,
   此时服务器进程会再次发送一个包含0字节数据的DATA报文
   (显然,该报文的总长度为4B=2B操作码+2B块号+0B数据);
9. TFTP协议中,用于读文件的连接和用于写文件的连接的建立方式不同

1.4 缺陷:

TFTP分组中并不提供用户名和口令。这是TFTP的一个特性(即"安全漏洞")

1.5 TFTP五种报文(操作码/功能及详解)

TFTP五种报文分别是: RRQ,WRQ,DATA,ACK和ERROR。

操作码/功能及详解:

1	RRQ 读请求,即下载
    模式字段包含:netascii 和 octet 两种
2	WRQ 写请求,即上传
3	DATA 数据包,即DATA
4	ACK 确认码,即ACK
5	ERROR 错误

1.5.1 RRQ 读请求/WRQ 写请求

模式字段中,包含两种字符串中的一种,"netascii"表示ASCII文件,"octet"表示二进制文件;

对于RRQ,客户向TFTP服务器发送读请求后,服务器返回一个块编号为1的DATA报文;
对于WRQ,客户向TFTP服务器发送写请求后,服务器返回的是块编号为1的ACK报文。
总之,不管是RRQ还是WRQ,接收DATA数据的一方(读者)发送ACK确认,而发送DATA数据(写者)的只负责发送数据。

1.5.2 DATA 数据包

由客户或服务器使用(由写者发送),用于传送数据块。

所有的块都用数字顺序编码,从1开始。

在所有的DATA报文中,这个块必须准确地等于512B(源码实现可修改),但最后一个块可以小于或等于512B。
当发送的DATA报文中数据部分的长度小于512B后,表示DATA报文发送完毕,所以小于数据部分512B的DATA数据报可以作为文件结束的标志。
特殊的情况是,当文件中的数据正好是512B的整数倍时,那么发送端必须再发送一个具有数据部分为0B的额外的DATA数据块以表示传输的结束。
数据可以采用ASCII码或二进制组来传送。

1.5.3 ACK 确认码

确认号表示它所收到的块号的一个确认

特殊情况是,当客户向服务器发送一个WRQ请求后,服务器返回给客户的是一个块号为0的ACK报文,表示服务器已经准备好了接收来自客户的数据报。

1.5.4 ERROR 错误

ERROR报文既可以有客户发送,也可以由服务器发送,

当一条连接(如读连接或写连接)不能建立或在数据传输中出现问题时使用。
差错码定义了差错的类型,差错信息是一个可变字节,包含原文中的差错数据。

1.5.5 说明:TFTP报文没有差错检验和字段

从上面的报文格式中可以看出,TFTP报文没有差错检验和字段,

所以接收端检验数据是否出现差错的唯一方法是通过分组该TFTP数据报的UDP首部中的检验和字段。

1.6 TFTP数据包格式

1.6.1 TFTP数据包格式

tftp 图
在这里插入图片描述

1.6.2 rrq/wrq可以带带扩展选项

如:

/etc/tftp/1.txt/0/octet/0/60000/0 
这个属于其扩展选项: 这个开源在模式后面塞了一个请求长度字段,协议属于扩展字段

格式:

optcode         filename         mode             opt1                 opt2
---------------------------------------------------------------------------------
	1        |      test.txt\0 |    octet\0    |   timeout\05\0 | blksize\01462\0 |
---------------------------------------------------------------------------------

参考:
https://blog.csdn.net/skyflying2012/article/details/34417905

1.7 TFTP传输过程描述

1.服务器使用端口号69被动打开连接;
2.客户主动打开连接,它使用临时端口作为源端口而端口69作为目的端口,向服务器进程发送RRQ报文;
3.服务器主动打开连接,它使用新的临时端口作为源端口,而使用收到的来自客户的临时端口作为目的端口,
向TFTP客户进程发送DATA报文(2B操作码,2B数据块的块号,512B数据);
4.客户收到服务器的报文后,发送4B的ACK(2B的操作码和2B的数据块号)给TFTP服务器,
告诉它之前发送给客户的数据报已经收到;
5.重复步骤3-4,直到所有请求的数据发送完毕。

tftp2 图
在这里插入图片描述

1.7.1 TFTP传输过程说明:

1. TFTP是一种类似于停止等待协议
   TFTP服务器只有收到客户端的确认报文ACK后才会向客户端接着发送新的数据。
   
2. 服务器向客户端发送数据的过程中,每次都是发送512B的数据,
	(512B的数据:源码实现可修改改,如60k均可,看下一篇代码实现)
   如果客户进程收到某个DATA报文中数据部分的长度小于512B,说明这是收到的最后一个报文;
   如果待发送的数据的总长度正好是512的整数倍,这就意味着最后一个数据报的长度正好为512B,
   此时服务器进程会再次发送一个包含0字节数据的DATA报文
   如果大于512则继续循环处理。
   (显然,该报文的总长度为4B的报文(2B操作码+2B块号+0B数据);
   
3. TFTP协议中,用于读文件的连接和用于写文件的连接的建立方式不同:
	3.1 建立读连接的时候,客户首先向服务器发送RRQ读报文,服务器收到该报文后,
	    直接发回给该客户DATA报文,并且包含第一个数据块(块号为1)。
	3.2而建立写连接的时候,客户首先先服务器发送WRQ写报文,服务器收到该报文后,
		则发回给客户ACK报文,使用的块号为0;
	上面两种情况如果遇到请求报文出错时,均会发回ERROR报文作为响应。

1.7.3 tftp数据交互图

tftp3 图
在这里插入图片描述

1.8 TFTP的流量控制

TFTP流量控制采用的是停止等待协议。

TFTP使用DATA报文发送数据块,并等待ACK报文的确认。若在超时之前发送端就收到了确认,它就发送下一个块。

这样,实现流量控制的方法是在发送下一个数据块之前,必须要保证收到了上一个数据块的ACK报文。

客户从服务器读文件:当客户打算向服务器读文件时,先发送RRQ报文,若无问题,服务器就直接发送块号为1的DATA报文(即第一个数据块就直接发送过去了)。
客户向服务器写文件(就是存储文件):当客户打算写文件时,先发送WRQ报文,若无问题,服务器就响应块号为0的ACK报文(不是DATA报文,因为此时服务器是数据接收方,只能发送ACK,同时注意第一个ACK的块编号是0,这样就可以通知客户,我同意了你的写请求)。客户在收到该确认后,就是用块号为1发送第一个数据块给服务器。

1.9 TFTP的差错控制

TFTP的差错机制与其他协议不同,它是对称的,

因为TFTP协议在发送端和接收端都使用了计时器。
(可看下一篇源码实现。)
也就是说,客户和服务器两端,一方使用了DATA报文计时器(发送端),另一方使用ACK报文计时器(接收端)。

若发送端丢失了数据报文,在计时器到期时发送端就重传该数据报文;
若接收端丢失了ACK报文,在超时时接收端就重传该ACK报文。

1.9.1 差错控制常用于这四种情况:

差错控制常用于这四种情况:报文受损、报文丢失、确认丢失和报文重复。

报文受损:当数据块出现差错(通过差错检验,得靠UDP首部)时,接收端能够检测出来并丢弃该报文。发送端等待确认,超时后就重传该数据报。
报文丢失:若数据报丢失了,它就用于不能到达接收方,而确认页不会发出。发送端在超时之后,就会重传该数据报。
确认丢失:确认丢失了,则可能发生两种情况:一是接收端的计时器比发送端的计时器先到期,则接收方重传确认;若发送端的计时器先期,则发送端重传该数据。
报文重复:接收端通过块编号可以检测出数据块的丢失。若数据块重复了,接收端就简单地将其丢弃。

1.10 扩展:UDP的 sendto() 和 recvfrom() 接口

1.10.1 UDP介绍

UDP(user datagram protocol)用户数据报协议,属于传输层。

1. UDP是面向非连接的协议,它不与对方建立连接,而是直接把数据报发给对方。
UDP无需建立类如三次握手的连接,使得通信效率很高。
2. 因此UDP适用于一次传输数据量很少、对可靠性要求不高的或对实时性要求高的应用场景。

1.10.2 UDP通信的过程图及说明

UDP通信的过程如图所示:

说明:

服务端:
  (1)使用函数socket(),生成套接字文件描述符;

  (2)通过struct sockaddr_in 结构设置服务器地址和监听端口;

  (3)使用bind() 函数绑定监听端口,将套接字文件描述符和地址类型变量(struct sockaddr_in )进行绑定;

  (4)接收客户端的数据,使用recvfrom() 函数接收客户端的网络数据;

  (5)向客户端发送数据,使用sendto() 函数向服务器主机发送数据;

  (6)关闭套接字,使用close() 函数释放资源;

客户端:
  (1)使用socket(),生成套接字文件描述符;

  (2)通过struct sockaddr_in 结构设置服务器地址和监听端口;

  (3)向服务器发送数据,sendto() ;

  (4)接收服务器的数据,recvfrom() ;

  (5)关闭套接字,close() ;

1.10.3 sendto

int sendto(int s, const void *buf, int len, unsigned int flags, 
			const struct sockaddr *to, int tolen);

返回值说明:

成功则返回实际传送出去的字符数,失败返回-1,错误原因会存于errno 中。

参数说明:

s:    socket描述符;
buf:  UDP数据报缓存区(包含待发送数据);
len:  UDP数据报的长度;
flags:调用方式标志位(一般设置为0);
to:  指向接收数据的主机地址信息的结构体(sockaddr_in需类型转换);
tolen:to所指结构体的长度;

1.10.4 recvfrom

int recvfrom(int s, void *buf, int len, unsigned int flags,
			struct sockaddr *from, int *fromlen); 

返回值说明:

成功则返回实际接收到的字符数,失败返回-1,错误原因会存于errno 中。

参数说明:

s:      socket描述符;
buf:    UDP数据报缓存区(包含所接收的数据); 
len:    缓冲区长度。 
flags:  调用操作方式(一般设置为0)。 
from:   指向发送数据的客户端地址信息的结构体(sockaddr_in需类型转换);
fromlen:指针,指向from结构体长度值。

例子参考下一篇博文:tftp源码实现

参考:
https://www.cnblogs.com/HpeMephisto/p/11312193.html

2. TFTP协议(2)TFTP源码实现

基于github 开源代码实现部分功能
https://github.com/ideawu/tftpx

下面自己写了一个可以正常跑的demo
https://blog.csdn.net/lqy971966/article/details/121819432

参考:

https://blog.csdn.net/qq_26440221/article/details/78337838
https://www.cnblogs.com/qingtianyu2015/p/5851551.html
https://blog.csdn.net/skyflying2012/article/details/34417905

  • 27
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值