TCP为了实现稳定可靠的传输,自然是需要在发送数据时附带一些信息,对端接收到报文段后将用户数据分离开存放在接收缓冲区,然后根据附加信息决定接下来的行为。所以即使TCP是面向字节流的传输协议,但是传输的基本单元却是报文段。
报文段由报文首部和数据组成,报文首部最小占20字节最多占60字节,固定的20字节包含各种连接信息,可扩展的40字节存放各种选项值
源端口和目的端口
各占2个字节,分别写入源端口号和目的端口号。比如客户端端口号10000,服务器端口号9999,那么客户端发送的报文段中源端口号为10000,目的端口号为9999。服务器发送的报文段相反
序列号
占4个字节,范围是 [0:232 [ 0 : 2 32 ]。表示数据的第一个字节的序列号,由于TCP的数据交互是基于序列号的(控制滑动窗口),发送方通过序列号控制发送数据以及超时重传,接收方通过序列号控制乱序重排
接收方可以根据第一个字节序列号 + 数据个数算出最后一个字节的序列号,并将其加一用作应答
当序列号增加到 232−1 2 32 − 1 后,会重新从0开始,由于 232 2 32 字节为4GB,可以保证重复使用的序列号代表的数据已经成功到达对端
确认号
占4个字节,表示期望下次收到的序列号。比如服务器收到客户端发来的报文段,其序列号字段值为501,并通过计算可知数据长度为200,所以服务器可以算出最后一个字节的序列号为700。这表明服务器正确收到了客户端发送的序列号到700为止的数据,因此,服务器期望下次收到的序列号为701,并将其作为确认号放入应答报文段中
确认号和序列号范围相同,当溢出时从0开始
数据偏移
占4位(注意这个单位是位,不是字节),表示TCP报文段的第一个数据距离报文段起始处有多远。由于TCP报文段首部长度不确定,20到60字节不等,所以需要一个字段用于找到数据起始处
数据偏移代表的是4字节的倍数,由于4位二进制最大可以表示15,所以数据偏移最大为4 * 15 = 60,这也是TCP报文段首部的最大长度
保留
占6位,目前不使用
控制位
TCP报文段首部存在6个控制位,用于说明报文段的性质,每个控制字段占1位
紧急URG
表示报文段中的数据是紧急数据,需要马上处理。接收方收到这种类型的报文段后,不会像正常流程那样将数据追加到接收缓冲区末尾,而是插到缓冲区开始的位置,这样应用程序就可以立即读取紧急数据
比如键入Ctrl + C时,就会将这条中断信息放在缓冲区头部,否则,只有当应用程序将之前的数据全部处理完才能够接收这个终止信息
该控制位需要配合紧急指针一同使用
确认ACK
只有当ACK位被置1时确认号才有用。TCP规定,连接建立后发送的所有报文段ACK位都必须置1
推送PSH
当发送方希望数据可以立即发送给对端时,TCP会将报文段首部的PSH位置1,接收方同样将PSH位置1的报文段中的数据尽快告知应用程序
该控制位很少使用,因为TCP会自己决定什么时候应该使用PUSH操作
复位RST
用于复位,表示连接出现错误,应当立即关闭。当TCP接收到复位报文段后会通知应用程序连接被复位,随后关闭连接
同步SYN
连接建立的过程中用于同步序列号,告知对方自己的起始序列号。可以根据对方的序列号初始化缓冲区起点(滑动窗口)
SYN=1,ACK=0时表示一个连接请求报文段,SYN=1,ACK=1表示一个连接接收报文段
终止FIN
用于释放连接,报文段中FIN控制位为1表示已经将数据发送完毕,等待关闭连接
窗口
占2个字节,表示发送该报文段的一方能够接收的字节数,用于控制对端发送数据的个数(控制对端滑动窗口)
窗口值范围为 [0,:216−1] [ 0 , : 2 16 − 1 ]
检验和
占2个字节,用于检验报文段是否出错。发送方根据发送的报文段计算检验和填入报文段首部,接收方根据接收的报文段重新计算,如果不匹配,表明报文段出错
紧急指针
占2个字节,表示紧急数据的个数,因为报文段中可以既包含紧急数据也可以包含普通数据,该字段用于区分二者
只有紧急URG控制位置1时才有效
选项
长度可变, 最长为40字节,当没有使用选项字段时,TCP报文段首部共20字节。
TCP选项比较常用的是MSS,即最大报文段长度。需要注意的是MSS指的是数据的最大长度而不是TCP报文段长度。在将数据发送之前,会根据MSS将数据进行合理的切分,即单次发送的报文段中的数据不能超过MSS,所以MSS应该适当调大一些以降低网络中的报文段个数