TCP协议详解

1.TCP/IP协议栈的基本格式

TCP协议详解

最后一层:以太网帧数据,分为帧头 和以太网数据和帧尾

第二层 以太网数据问部分(IP数据): IP头 和IP 数据

第三层TCP或UDP数据:TCP/UDP头 ,TCP/UDP数据

第四层TCP/UDP数据层: 应用数据 (Http头,Http数据)

2.TCP协议头

TCP协议详解

源端口和目的端口

     各占2个字节,这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。有时一个IP地址和一个端口号也称为socket(插口)。

序号(seq)

     占4个字节,是本报文段所发送的数据项目组第一个字节的序号。在TCP传送的数据流中,每一个字节都有一个序号。例如,一报文段的序号为300,而且数据共100字节,

则下一个报文段的序号就是400;序号是32bit的无符号数,序号到达2^32-1后从0开始。

在TCP中,数据不是按包排序的,而是按字节排。每个包的Seq Number代表的是发送字节的起始序号。

发送的第一个包的初始序号是随机的,在创建连接的三次握手过程中交换。

确认序号(ack) Acknowledgment Number

     占4字节,是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个报文段的首部中的序号;确认序号应该是上次已成功收到数据字节序号+1。

只有ACK标志为1时,确认序号才有效。没有收到就一直发,通过Sequence Number 与该信息保证有序和可靠性。

在TCP中,Ack Number代表的是希望对方发送数据的起始位置。

例如: A向B发送了一个数据包,其Seq Number 为1000,其大小为1000字节,则B收到该包后,返回的Ack Number为2001.

数据偏移(Data offset)

      占4比特,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。数据偏移以32位为长度单位,

也就是4个字节,因此TCP首部的最大长度是60个字节。即偏移最大为15个长度单位=1532位=154字节。

决定TCP数据从什么地方开始,因为Options字段长度是不定的。

 

保留

     6比特,供以后应用,现在置为0。

6个标志位比特

① URG:当URG=1时,注解此报文应尽快传送,而不要按本来的列队次序来传送。与“紧急指针”字段共同应用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号,

              使接管方可以知道紧急数据共有多长。

② ACK:只有当ACK=1时,确认序号字段才有效;当目的收到数据发确认消息。

③ PSH:当PSH=1时,接收方应该尽快将本报文段立即传送给其应用层。

④ RST:当RST=1时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个不法的报文段或拒绝打开一个连接;说明对方 没有提供服务,或对方认为你的连接是有问题的。

⑤ SYN:SYN=1,ACK=0时表示请求建立一个连接,携带SYN标志的TCP报文段为同步报文段;三次握手,每个数据包都要设置

⑥ FIN:发端完成发送任务。挥手要设置。(收到fin后也需要发一个fin)

窗口(Window)

     在发送数据是一下子发送几个包,然后确认只需要确认最后一次发送,然后到底要发多个包再通知由窗口大小来决定。 

     TCP通过滑动窗口的概念来进行流量控制。设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制, 协调好

通信双方的工作节奏。所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓 冲区。窗口大小为

字节数起始于确认序号字段指明的值(这个值是接收端正期望接收的字节)。窗口大小是一个16bit字段,因而窗口大小最大为65535字节。

检验和

       检验和覆盖了整个TCP报文段:TCP首部和数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。

紧急指针

      只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。

Options: 选项, 用来设置一些附加项,比如:可以传输的最大报文大小是多少,

这部分最多包含40字节,因为TCP头部最长是60字节(其中还包含前面讨论的20字节的固定部分)。典型的TCP头部选项结构如下图所示。

TCP协议详解

 

选项的第一个字段kind说明选项的类型。有的TCP选项没有后面两个字段,仅包含1字节的kind字段。第二个字段length(如果有的的话)指定该选项的总长度,该长度包括kind字段和length字段占据的2字节。第三个字段info(如果有的话)是选项的具体信息。常见的TCP选项有7中,如下图

TCP协议详解

kind=0是选项表结束选项。

kind=1是空操作(nop)选项,没有特殊含义,一般用于将TCP选项的总长度填充为4字节的整数倍。

kind=2是最大报文段长度选项。TCP连接初始化时,通信双方使用该选项来协商最大报文段长度(Max Segement Size,MSS)。TCP模块通常将MSS设置为(MTU-40)字节(减掉的这40字节包括20字节的TCP头部和20字节的IP头部)。这样携带TCP报文段的IP数据报的长度就不会超过MTU(假设TCP头部和IP头部都不包含选项字段,并且这也是一般情况),从而避免本机发生IP分片。对以太网而言,MSS值是1460(1500-40)字节。

kind=3是窗口扩大因子选项。TCP连接初始化时,通信双方使用该选项来协商接收通告窗口的扩大因子。在TCP的头部中,接收通告窗口大小时用16位表示的,故最大为65535字节,但实际上TCP模块允许的接收通告窗口大小远不止这个数(为了提高TCP通信的吞吐量)。窗口扩大因子解决了这个问题。假设TCP头部中的接收通告窗口大小是N乘2的M次方,或者说N左移M位。注意,M的取值范围是0~14。我们可以通过修改/proc/sys/net/ipv4/tcp_window_scaling内核变量来启用或关闭窗口扩大因子选项。

kind=5是SACK实际工作的选项。该选项的参数告诉发送方本端已经收到并缓存的不连续的数据块,从而让发送端可以据此检查并重发丢失的数据块。每个块边沿(edge of block)参数包含一个4字节的序号。其中块左边沿表示不连续块的第一个数据的序号,而块右边沿则表示不连续块的最后一个数据的序号的下一个序号。这样一对参数(块左边沿和块右边沿)之间的数据是没有收到的。因为一个块信息占用8字节,所以TCP头部选项中实际上最多可以包含4个这样的不连续数据块(考虑选项类型和长度占用的2字节)。

kind=8是时间戳选项。该选项提供了较为准确的计算通信双方之间的回路时间(Round Trip Time,RTT)的方法,从而为TCP流量控制提供重要信息。我们可以通过修改/proc/sys/net/ipv4/tcp_timestamps内核变量来启用或关闭时间戳选项。

Padding:由于Options大小不定,但需要保证32位对齐,所以就使用Padding进行补齐。

 

Data :

 

以下是抓到的一个TCP报文段:

TCP协议详解

从图中可以看出源端口号58991对应e66f,目的端口号443,对应01bb,Flags为SYN,表示请求一个连接,因此它是一个同步报文段。这里seq表示的是相对序号,因为该同步报文段是从180.85.25.164到74.125.204.100的第一个TCP报文段,所以该序号值也就是此次通信过程中该传输方向的ISN值,则相对序号即为0。并且,因为这是通信过程中第一个TCP报文段,所以它没有针对对方发送来的TCP报文段的确认值(尚未收到任何对方发来的TCP报文段)。

window size是接收通告窗口大小,因为这是一个同步报文段,所以win值反映的是实际的接收通告窗口大小。