TCP是可靠的运输层协议。这就表示应用层程序把数据流交付给TCP后要依靠TCP把整个数据流交付给另一端的应用程序,并且是按序的,没有差错、也没有任何一部分丢失或重复。
TCP使用差错控制来提供可靠性。差错控制包括以下的一些机制:检测和重传受到损伤的报文段、重传丢失的报文段、保存失序到达的报文段直至缺失的报文到期,以及检测和丢弃重复的报文段。TCP通过三个简单的工具来完成其差错控制:检验和、确认以及超时。
检验和
每个报文都包含了一个检验和字段,用来检查报文段是否收到损伤。如果某个报文段因检验和无效而被检查出受到损伤,就由终点TCP将其丢弃,并被认为是丢失了。TCP规定每个报文段都必须使用16位的检验和。
确认
TCP采用确认来证实收到了报文段。控制报文段不携带数据,但需要消耗一个序号,它也需要被确认,而ACK报文段永远不需要确认【ACK报文段不消耗序号,也不需要被确认】。
在以前,TCP只使用一种类型的确认:积累确认。目前有一些TCP实现还采用了选择确认。
积累确认(ACK)
TCP最初的设计是对收到的报文段进行积累确认。接收方通告它期望接收的下一个字节的序号,并忽略所有失序到达并被保存的报文段。有时这被称为肯定积累确认或ACK。“肯定”这个词表示对于那些丢弃的、丢失的或重复的报文段都不提供反馈。在TCP首部的32位ACK字段用于积累确认,而它的值仅在ACK标志为1时才有效。
选择确认(SACK)
现在越来越多的实现又增加另一种类型的确认,称为选择确认(selective acknowledgment)或SACK。SACK并没有取代ACK,而是向发送方报告了更多的信息。SACK要报告失序的数据块以及重复的报文段块(即受到不止一次)。但是,在TCP首部中并没有提供增加这类信息的地方,因此SACK是作为TCP首部末尾的选项来实现的。
产生确认
接收方在什么时候产生?在TCP的发展历程曾经定义过好几种规则,并用在多个实现中。这里我们给出几个最常用的规则。这些规则的顺序并不代表其重要性。
1、当A端向B端发送数据报文段时,必须包含(捎带)一个确认,它给出A端期望接收的下一个序号。这条规则减少了所需要的报文段的数量,因此也减少了通信量。
2、当接收方没有数据要发送,但是收到了按序到达(序号是所期望的)的报文段,同时前一个报文段也已经确认过了,那么接收方就推迟发送确认报文段,直到另一个报文段到达,或经过了一段时间(通常是500ms