linux网络编程之TCP/IP基础(五) 分析一帧基于UDP的TFTP协议帧

下图是UDP的段格式:

相比TCP段格式,UDP要简单得多,也没啥好 说的,需要注意的是UDP数据长度指payload加上首部的长度。

下面分析一帧基于UDP的TFTP协议帧:

以太网 首部

0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00

IP首部

0000: 45 00

0010: 00 53 93 25 00 00 80 11 25 ec c0 a8 00 37 c0 a8

0020: 00 01

UDP首部

0020: 05 d4 00 45 00 3f ac 40

TFTP协议

0020: 00 01 'c' ':' '\' 'q'

0030: 'w' 'e' 'r' 'q' '.' 'q' 'w' 'e' 00 'n' 'e' 't' 'a' 's' 'c' 'i'

0040: 'i' 00 'b' 'l' 'k' 's' 'i' 'z' 'e' 00 '5' '1' '2' 00 't' 'i'

0050: 'm' 'e' 'o' 'u' 't' 00 '1' '0' 00 't' 's' 'i' 'z' 'e' 00 '0'

0060: 00

以太网首部:源MAC地址是00:05:5d:61:58:a8,目的MAC地址是 00:05:5d:67:d0:b1,上层协议类型0x0800表示IP。

IP首部:每一个字节0x45包含4位版本号和4位首部长度,版本号 为4,即IPv4,首部长度为5,说明IP首部不带有选项字段。服务类型为0,没有使用服务。16位总长度字段(包括IP首部和 IP层payload的长度)为0x0053,即83字节,加上以太网首部14+4字节可知整个帧长度是101字节。IP报标识是0x9325,标志 字段和片偏移字段设置为0x0000,就是DF=0允许分片,MF=0此数据报没有更多分片,没有分片偏移。TTL是0x80,也就是128 。上层协议0x11表示UDP协议。IP首部校验和为0x25ec,源主机IP是c0 a8 00 37(192.168.0.55),目的主机IP是c0 a8 0001(192.168.0.1)。

UDP首部:源端口号0x05d4(1492)是客户端的端口号,目的端口号0x0045(69)是TFTP服 务的well-known端口号。UDP报长度为0x003f,即63字节,包括UDP首部和UDP层payload的长度。UDP首部和UDP层payload的 校验和为0xac40。

TFTP是基于文本的协议,各字段之间用字节0分隔,开头的00 01表示请求读取一个文件,接下来 的各字段是:
c:\qwerq.qwe

netascii

blksize 512

timeout 10

tsize 0

就我个人而言,学习tcp/ip 时最容易迷糊的就是那些数据大小,头部大小什么的,现在来总结一下,也许大家会清晰一点:

耐心地数一下,可 知道tftp的纯数据供55字节(udp payload),加上udp头部8字节,就是63字节,也就是前面说的UDP 头部字段记录的UDP数 据长度,再加上ip头部20字节,也就是83字节,即前面说的ip头部记录的ip包大小,即udp payload + udp头部 可以当作ip 层的payload,ip层payload + ip头部 = 83字节,加上以太网头部14字节,尾部校验4字节,总共101字节,即完整的一帧数 据帧。

一般的网络通信都是像TFTP协议这样,通信的双方分别是客户端和服务器,客户端主动发起请求(上面的例 子就是客户端发起的请求帧),而服务器被动地等待、接收和应答请求。客户端的IP地址和端口号唯一标识了该主机上的 TFTP客户端进程,服务器的IP地址和端口号唯一标识了该主机上的TFTP服务进程,由于客户端是主动发起请求的一方,它必 须知道服务器的IP地址和TFTP服务进程的端口号,所以,一些常见的网络协议有默认的服务器端口,例如HTTP服务默认TCP 协议的80端口,FTP服务默认TCP协议的21端口,TFTP服务默认UDP协议的69端口(如上例所示)。在使用客户端程序时,必 须指定服务器的主机名或IP地址,如果不明确指定端口号则采用默认端口,可以查阅ftp、tftp等程序的man page了解如何 指定端口号。/etc/services中列出了所有well-known的服务端口和对应的传输层协议,这是由IANA(Internet Assigned Numbers Authority)规定的,其中有些服务既可以用TCP也可以用UDP,为了清晰,IANA规定这样的服务采用相同的TCP或 UDP默认端口号,而另外一些TCP和UDP的相同端口号却对应不同的服务。

很多服务有well-known的端口号,然而客户 端程序的端口号却不必是well-known的,往往是每次运行客户端程序时由系统自动分配一个空闲的端口号,用完就释放掉, 称为ephemeral的端口号。

UDP协议不面向连接,也不保证传输的可靠性,例如:

1、发送端的UDP协议层只管 把应用层传来的数据封装成段交给IP协议层就算完成任务了,如果因为网络故障该段无法发到对方,UDP协议层也不会给应 用层返回任何错误信息。

2、接收端的UDP协议层只管把收到的数据根据端口号交给相应的应用程序就算完成任务了 ,如果发送端发来多个数据包并且在网络上经过不同的路由,到达接收端时顺序已经错乱了,UDP协议层也不保证按发送时 的顺序交给应用层。

3、通常接收端的UDP协议层将收到的数据放在一个固定大小的缓冲区中等待应用程序来提取和 处理,如果应用程序提取和处理的速度很慢,而发送端发送的速度很快,就会丢失数据包,UDP协议层并不报告这种错误。

因此,使用UDP协议的应用程序必须考虑到这些可能的问题并实现适当的解决方案,例如等待应答、超时重发、为数 据包编号、流量控制等。一般使用UDP协议的应用程序实现都比较简单,只是发送一些对可靠性要求不高的消息,而不发送 大量的数据。例如,基于UDP的TFTP协议一般只用于传送小文件(所以才叫trivial的ftp),而基于TCP的FTP协议适用于各 种文件的传输。

时间: 2024-10-31 20:58:41

linux网络编程之TCP/IP基础(五) 分析一帧基于UDP的TFTP协议帧的相关文章

linux网络编程之TCP/IP基础(一) TCP/IP协议栈与数据包封装

一.ISO/OSI参考模型 OSI(open system interconnection)开放系统互联模型是由ISO(International Organization for Standardization)国际标准化组织定义的网络分层模型,共七层,如下图. 物理层(Physical Layer):物 理层定义了所有电子及物理设备的规范,为上层的传输提供了一个物理介质,本层中数据传输的单位为比特(bit).属于 本层定义的规范有EIA/TIA RS-232.EIA/TIA RS-449.V

linux网络编程之TCP/IP基础(四) TCP连接的建立和断开、滑动窗口

一.TCP段格式: TCP的段格式如下图所示 源端口号与目的端口号 源端口号和目的端口号,加上IP首部的源IP地址和目的IP地址唯一确定一个TCP连接. 序号 序号表示在这个报文段中的第一个数据字节序号. 确认号 仅当ACK标志为1时有效.确认号表示期望收到 的下一个字节的序号. 头部长度 4位,TCP头部最多60个字节,最少20个字节 保留位 6位,必须为 0 6个标志位 URG-紧急指针有效 ACK-确认序号有效 PSH-接收方应尽快将这个报文段交给应用层 RST- 连接重置 SYN-同步序

linux网络编程之TCP/IP基础(三) IP数据报格式和IP地址路由

一.IP数据报格式 IP数据报格式如下: 版本 IP协议版本号,长度为4位,IPv4此 字段值为4,IPv6此字段值为6 首部长度 以32位的字为单位,该字段长度为4位,最小值为5,即不带任何选项的IP 首部20个字节:最大值为15,所以首部长度最大为60个字节 服务类型(TOS) 长度为8位.此字段包含3位的优先 权(现已忽略),4位的服务类型子字段和1位的保留位(必须置0).4位的服务类型分别为最小延迟(D).最大吞吐量(T ).最高可靠性(R).最小费用(F),如下图. 总长度 该字段长度

linux网络编程之TCP/IP基础(二) 利用ARP和ICMP协议解释ping命令

一.MTU 以太网和IEEE 802.3对数据帧的长度都有限制,其最大值分别是1500和1492字节,将这个限制称作最大 传输单元(MTU,Maximum Transmission Unit) 如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大, 那么IP层就要进行分片(Fragmentation),把数据报分成若干片,这样每一片都小于MTU. 当网络上的两台主机互相 进行通信时,两台主机之间要经过多个网络,每个网络的链路层可能有不同的MTU,其中两台通信主机路径中的最小MTU被称

Linux网络编程之TCP协议(基础班)

学习TCP协议和UDP协议真的简单,这里的简单的指的是入门,如果需要升入研究那就不是那么简单了. 直接看代码是学习程序的最好方法. server.c             /* 服务器端 */ #include <sys/types.h>          /* See NOTES */ #include <sys/socket.h> #include <string.h> #include <sys/socket.h> #include <neti

linux网络编程之socket(十五) UNIX域套接字编程和socketpair 函数

一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机 制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是 UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包.计算校验和.维护序号和应答等,只是 将应用层数据从一个进程拷贝到另一个进程.UNIX域套接字与TCP套接字相比较,

Linux网络编程之TCP协议

server.c: #include <stdlib.h>  #include <stdio.h>  #include <errno.h>  #include <string.h>  #include <netdb.h>  #include <sys/types.h>  #include <netinet/in.h>  #include <sys/socket.h>  #define portnumber 88

linux 网络编程之TIME_WAIT状态

                                                         Linux 网络编程之TIME_WAIT状态                                                               刚刚开始看TCP socket的4次握手终止流程图的时候,对于最后的TIME_WAIT状态不是很理解.现在在回过头来研究,发现TIME_WAIT状态是一个很微妙状态.之所以设计TIME_WAIT状态的原因有2个原因:

Linux网络编程之UDP Socket程序示例_C 语言

在网络传输协议中,TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接.TCP有一种"重传确认"机制,即接收端收到数据后要发出一个肯定确认的信号,发送端如果收到接收端肯定确认的信号,就会继续发送其他的数据,如果没有,它就会重新发送. 相对而言,UDP协议则是一种无连接的,不可靠的数据报(SOCK_DGRAM)传输服务.使用UDP套接口不用建立连接,服务端在调用socket()生成一个套接字并调用bind()绑定端口后就可