TCP虽然是面向字节流的,但是TCP传送的数据单元却是报文段。一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在它首部的各字段的作用。TCP报文段首部的前20字节是固定的,后面有4n(n为整数)字节是根据需要而增加的选项。因此TCP首部的最小长度是20字节。
首部固定部分各字段的含义如下
- 源端口目的端口(Source Port、Destination Port)
各占2个字节,TCP的分用功能也是通过端口实现的 - 序号(Sequence number)
占4字节,序号范围是[0, 2^32 - 1],共2^32(即4294967296,即4G字节)个序号。序号增加到 2^32 - 1 后,下一个序号又回到0。也就是是说,序号使用mod 2^32运算,TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按照顺序编号。整个要传送的字节流的起始序号必须在建立连接是设置。首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号。例如,一报文段的序号字段值是301,而携带的数据共有100字节。这就表明:本报文段数据的第一个字节的序号是301,最后一个字节的序号是400。显然下一个报文段(如果还有的话)的数据序号从401开始,即下一个报文段的序号字段值为401,这个字段的名称也叫做“报文段序号”。**注意**:在传输的两个方向上字节流序号是没有关系的,即假设客户端向服务端的初始序号是x,服务端向客户端发送的初始序号是y,那么x和y没有必然的联系,而是 - 确认号(Acknowledge number)
占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。例如,B正确收到了A发送过来的一个报文段,其序号字段的值为501,而数据字段长度是200字节,这表明B正确收到了A发送的到序号700为止的数据,因此,B期望收到A的下一个数据字节序号是701,于是B在发送给A的确认报文段中把确认号置为701。**总结**:若我收到报文段ack为N,则表明对方已收到序号N-1为止的所有数据,下一次对方期望收取到我发送序号为N的报文段。 - 数据偏移
占4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。这个字段实际上是指出TCP报文段的首部长度。由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。但应注意,“数据偏移”的单元是32位(4字节为计算单位)。因此数据偏移的最大值是60字节:(2^4bit-1) * 4Byte
,这也是TCP首部的最大长度(即选项字段长度不能超过40字节) - 保留
占6位,目前置为0
接下来的6个控制位说明本报文段的性质
- 紧急URG
当URG=1时,表明紧急指针字段有效。使当前报文段有最高的发送优先级,而不按照原来的排队顺序俩传送。比如Ctrl+C中断指令就需要用到URG。当URG=1时,发送应用进程就告诉发送方TCP有紧急数据要传送。于是发送方TCP就把紧急数据插入到本报文段的最前面,而在紧急数据后面的数据任然是普通的数据。 - 确认ACK
仅当ACK=1时有效,ACK=0时无效,TCP规定,在连接建立后所有传送的报文段都必须把ACK置为1. - 推送PSH
当两个应进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应,在这种情况下,TCP就可以使用推送PSH操作。这时,发送方的TCP把PSH置1,并立即建立一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快交付接受应用进程,而不等到整个缓存都填满了后再交付。 - 复位RST
当RST=1时,表明TCP连接中出现严重的错误(由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。RST置1还用来拒绝一个非法的报文段或拒绝打开一个连接。RST也可以称为重建位或者重置位。 - 同步SYN
在建立连接时用来同步序号。当SYN=1且SCK=0时,表明这时一个连接请求报文段。若对方同意建立连接,则应在响应报文段中使SYN=1和ACK=1,。 - 终止FIN
用来释放一个连接,当FIN=1时,表示此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
- 窗口
占2字节,窗口值是[0, 2^16-1]之间的整数。窗口指的是发送本报文段的一方的接收窗口。窗口值告诉对方:从本报文段首部中的ack算起,接收方目前允许对方发送的数据量。之所以有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。例如,假设确认号是701,窗口字段是1000,这就表明从701号算起,发送此豹纹的的一方还有接受1000个字节的数据的接受缓存空间。注意:窗口值是经常在动态变化着的。 - 检验和
占2个字节,检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12个字节的伪首部。伪首部与UDP用户数据报的伪首部一样,但应该把伪首部第4个字段中的17改为6(TCP协议号为6),把第五个字段中的UDP长度改为TCP长度。接收方收到此报文段后,任要加上伪首部来计算校验和。 - 紧急指针
占2字节,紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据字节数(紧急数据结束后就是普通数据)。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。当所有的紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据。 - 选项
长度可变,最长可达40字节。当没有使用选项时,TCP的首部长度是20字节。 - 选项1:MSS(Maximum Segment Size)最大报文段长度。指的是每一个TCP报文段中的数据字段的最大长度,请注意:MSS的值和接收窗口值没有关系。在连接建立的过程中,双方都把自己能够支持的MSS写入这一字段,以后就按照这个值传送数据,两个传送方向可以有不同的MSS值。若主机未填写这一项,则MSS的默认值是536字节长。因此所有在英特网上的主机都能接受的报文段长度是536+20=556字节
- 选项2:窗口扩大选项。我们知道TCP首部中窗口字段长度是16位,因此最大的窗口大小为64K字节,限制了传输速度。窗口扩大选项占3字节。
- 选项3:时间戳选项
- 选项4:选择确认选项