您的位置:首页 > 理论基础 > 计算机网络

TCP/IP 协议簇的逐层封装

2015-02-02 21:01 120 查看
在使用 TCP 协议的网络程序中,用户数据从产生到从网卡发出去一般要经过如下的逐层封装过程:



从下往上看:

1)链路层通过加固定长度的首部、尾部来封装 IP 数据报(Datagram) 产生以太网帧(Frame)。 其中首部存在对封装数据的标识:是 IP(0x0800,例如本例) 、ARP(0x0806) 还是 RARP(0x0835)。

2)网络层通过加 IP首部来封装 TCP 段(Segment) 产生 IP 数据报。 其中首部存在对封装数据的标识:是 ICMP(0x01)、IGMP(0x02)、TCP(0x06,例如本例)还是 UDP(0x11)。

3)传输层通过加首部来封装应用数据产生 TCP 段。其中TCP首部存在对封装数据的标识:端口号,来标识是那个应用程序产生的数据。
4)按这种处理逻辑,在应用层,对于我们要处理的应用数据理所当然的加上固定长度的首部,首部中同样含有某些标识,标识些什么呢?按经验,一般会标识本次数据的业务意义,在程序中一般处理为业务集合(枚举型)的某个元素;如果是 TCP应用(本例) 还可能包括应用数据总体长度。

Ethernet、Tcp、Udp 等协议的数据包格式
TCP/IP协议是一个比较复杂的协议集,有很多专业书籍介绍。在此,我仅介绍其与编程密切相关的部分:以太网上 TCP/IP 协议的分层结构及其报文格式。我们知道TCP/IP 协议采用分层结构,其分层模型及协议如下表:



协议采用分层结构,因此,数据报文也采用分层封装的方法。下面以应用最广泛的以太网为例说明其数据报文分层封装,如下图所示:



任何通讯协议都有独特的报文格式,TCP/IP 协议也不例外。对于通讯协议编程,我们首先要清楚其报文格式。由于TCP/IP 协议采用分层模型,各层都有专用的报头,以下就简单介绍以太网下 TCP/IP 各层报文格式。



8 字节的前导用于帧同步,CRC 域用于帧校验。这些用户不必关心其由网卡芯片自动添加。目的地址和源地址是指网卡的物理地址,即 MAC 地址,具有唯一性。帧类型或协议类型是指数据包的高级协议,如 0x0806 表示 ARP 协议,0x0800 表示 IP 协议等。之所以要把数据组合成以帧为单位传送,是为了在出错时,可只将有错的帧重发,而不必将全部数据重新发送,从而提高了效率。注:数据以帧为单位进行发送,若某一帧有差错,以后就重传这个出错的帧。一个帧要有帧界限,接收端在收到比特流后,能够依据帧界限正确知道哪些比特构成一个帧。接收端找到帧定界符并确定帧的准确位置,就是完成了帧同步。



硬件类型:指明了发送方想知道的硬件接口类型,以太网的值为1;

协议类型:指明了发送方提供的高层协议类型,IP为0800(16进制);

硬件地址长度和协议长度:指明了硬件地址和高层协议地址的长度,这样ARP报文就可以在任意硬件和任意协议的网络中使用;

操作类型:用来表示这个报文的类型,ARP请求为1,ARP响应为2,RARP请求为3,RARP响应为4;

发送方硬件地址(0-3字节):源主机硬件地址的前3个字节;

发送方硬件地址(4-5字节):源主机硬件地址的后3个字节;

发送方IP地址(0-1字节):源主机硬件地址的前2个字节;

发送方IP地址(2-3字节):源主机硬件地址的后2个字节;

目标硬件地址(0-1字节):目的主机硬件地址的前2个字节;

目标硬件地址(2-5字节):目的主机硬件地址的后4个字节;
目标IP地址(0-3字节):目的主机的IP地址。

IP 数据报头格式如下图:



版本号(Version):长度4比特。标识目前采用的IP协议的版本号。一般的值为0100(IPv4),0110(IPv6)

IP包头长度(Header Length):长度4比特。描述IP包头的长度。因为在IP包头中有变长的可选部分。该部分占4个bit位,单位为32bit(4个字节),即本区域值= IP头部长度(单位为bit)/(8*4),因此,一个IP包头的长度最长为“1111”,即15*4=60个字节。IP包头最小长度为20字节。

服务类型(Type of Service):长度8比特。这八位被分成如下定义,其中PPP三位组合使用:PPP
DTRC0

PPP:定义包的优先级,取值越大数据越重要

000 普通 (Routine)

001 优先的 (Priority)

010 立即的发送 (Immediate)

011 闪电式的 (Flash)

100 比闪电还闪电式的 (Flash Override)

101 CRI/TIC/ECP(找不到这个词的翻译)

110 网间控制 (Internetwork Control)

111 网络控制 (Network Control)

D 时延: 0:普通 1:延迟尽量小

T
吞吐量: 0:普通 1:流量尽量大

R 可靠性: 0:普通 1:可靠性尽量大

M 传输成本: 0:普通 1:成本尽量小

0
最后一位被保留,恒定为0

IP包总长(Total Length):长度16比特。
以字节为单位计算的IP包的长度 (包括头部和数据),所以IP包最大长度65535字节。

标识符(Identifier):长度16比特。该字段和Flags和Fragment Offest字段联合使用,对较大的上层数据包进行分段(fragment)操作。路由器将一个包拆分后,所有拆分开的小包被标记相同的值,以便目的端设备能够区分哪个包属于被拆分开的包的一部分。

标记(Flags):长度3比特。该字段第一位不使用。第二位是DF(Don't Fragment)位,DF位设为1时表明路由器不能对该上层数据包分段。如果一个上层数据包无法在不分段的情况下进行转发,则路由器会丢弃该上层数据包并返回一个错误信息。第三位是MF(More Fragments)位,当路由器对一个上层数据包分段,则路由器会在除了最后一个分段的IP包的包头中将MF位设为1。

片偏移(Fragment Offset):长度13比特。表示该IP包在该组分片包中位置,接收端靠此来组装还原IP包。

生存时间(TTL):长度8比特。当IP包进行传送时,先会对该字段赋予某个特定的值。当IP包经过每一个沿途的路由器的时候,每个沿途的路由器会将IP包的TTL值减少1。如果TTL减少为0,则该IP包会被丢弃。这个字段可以防止由于路由环路而导致IP包在网络中不停被转发。

协议(Protocol):长度8比特。标识了上层所使用的协议。

以下是比较常用的协议号:

1 ICMP

2 IGMP

6 TCP

17 UDP

88 IGRP

89 OSPF

头部校验(Header
Checksum):长度16位。用来做IP头部的正确性检测,但不包含数据部分。 因为每个路由器要改变TTL的值,所以路由器会为每个通过的数据包重新计算这个值。

起源和目标地址(Source and Destination Addresses):这两个地段都是32比特。标识了这个IP包的起源和目标地址。要注意除非使用NAT,否则整个传输的过程中,这两个地址不会改变。

至此,IP包头基本的20字节已介绍完毕,此后部分属于可选项,不是必须的部分。

可选项(Options):这是一个可变长的字段。该字段属于可选项,主要用于测试,由起源设备根据需要改写。可选项目包含以下内容:

松散源路由(Loose source routing):给出一连串路由器接口的IP地址。IP包必须沿着这些IP地址传送,但是允许在相继的两个IP地址之间跳过多个路由器。

严格源路由(Strict source routing):给出一连串路由器接口的IP地址。IP包必须沿着这些IP地址传送,如果下一跳不在IP地址表中则表示发生错误。

路由记录(Record route):当IP包离开每个路由器的时候记录路由器的出站接口的IP地址。

时间戳(Timestamps):当IP包离开每个路由器的时候记录时间。

填充(Padding):因为IP包头长度(Header Length)部分的单位为32bit,所以IP包头的长度必须为32bit的整数倍。因此,在可选项后面,IP协议会填充若干个0,以达到32bit的整数倍。

typedef struct _iphdr //定义IP首部  
{  
unsigned char h_lenver; //4位首部长度+4位IP版本号  
unsigned char tos; //8位服务类型TOS  
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识  
unsigned short frag_and_flags; //3位标志位  
unsigned char ttl; //8位生存时间 TTL  
unsigned char proto; //8位协议 (TCP, UDP 或其他)  
unsigned short checksum; //16位IP首部校验和 
unsigned int sourceIP; //32位源IP地址  
unsigned int destIP; //32位目的IP地址  
}IP_HEADER;

我们用单片机实现 TCP/IP 协议要作一些简化,不考虑数据分片和优先权。因此,在此我们不讨论服务类型和标志偏移域,只需填“0” 即可。协议“版本”为 4,“头长度”单位为 32Bit,“总长度”以字节为单位,表示整个 IP 数据报长度。“标识”是数据包的 ID 号,用于识别不同的 IP 数据包。“生存时间” TTL 是个数量及的概念,防止无用数据包一直存在网络中。一般每经过路由器时减一,因此通过 TTL
可以算出数据包到达目的地所经过的路由器个数。“协议”域表示创建该数据包的高级协议类型。如 1 表示 ICMP 协议,6 表示 TCP 协议,17 表示 UDP 协议等。IP 数据包为简化数据转发时间,仅采用头校验的方法,数据正确性由高层协议保证。

ICMP(网间网控制报文协议)协议 应用广泛。在此仅给出最常见的回应请求与应答报文格式, 用户命令 ping 便是利用此报文来测试信宿机的可到达性。 报文格式如下图所示:



类型 0 为回应应答报文,8 为回应请求报文。整个数据包均参与检验。注意 ICMP 封装在 IP 数据包里传送。





TCP 是面向连接的可靠数据传输协议,因此比较复杂,在此仅作简单介绍。“序号”指数据在发送端数据流中的位置。“确认号”指出本机希望下一个接收的字节的序号。与 IP 校验不同的是 TCP,UDP 校验采用伪头标加整个报文一同校验的方法。TCP 协议工作原理另行介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: