1.TCP超时重传时间的选择

2.TCP可靠传输的实现
TCP基于以字节为单位的滑动窗口来实现可靠传输
- 发送方在未收到接收方的确认时,可将发送窗口内还未发送的数据全部发送出去;
- 接收方只接收序号落入发送窗口的数据
虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的发送窗口并不总是和接收方的接收窗口一样大。
- 网络传送窗口值需要经历一定的时间滞后,并且这个时间还是不确定的。
- 发送方还可能根据网络当时的拥塞情况适当减小自己的发送窗口尺寸。
对于不按序到达的数据应如何处理,TCP并无明确规定。
- 如果接收方把不按序到达的数据一律丢弃,那么接收窗口的管理将会比较简单,但这样做对网络资源的利用不利,因为发送方会重复传送较多的数据。
- TCP通常对不按序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。
TCP要求接收方必须有累积确认和捎带确认机制,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。
- 接收方不应过分推迟发送确认,否则会导致发送方不必要的超时重传,这反而浪费了网络的资源。
- TCP标准规定,确认推迟的时间不应超过0.5秒。若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认[RFC 1122]。捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。
TCP的通信是全双工通信。通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和接收窗口。在谈到这些窗口时,一定要弄消口时,一定要弄清楚是哪一方的窗口。

3.TCP 的运输连接管理
3.1TCP的连接建立
TCP的连接建立要解决以下三个问题:
1 使TCP双方能够确知对方的存在;
2 使TCP双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等);
3 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。

3.2TCP 的连接释放

三次握手(建立连接)
三次握手确保客户端和服务器都准备好发送和接收数据,并同步序列号。
第一次握手(SYN):
客户端发送一个TCP报文段,其中SYN标志位设置为1,并选择一个初始序列号(Sequence Number,例如seq=x)。这个报文段不携带应用层数据。
客户端进入SYN_SENT状态,等待服务器的确认。
第二次握手(SYN+ACK):
服务器收到客户端的SYN报文段后,如果同意建立连接,则发送一个应答报文段。该报文段的SYN和ACK标志位都设置为1,确认号(Acknowledgment Number)为x+1(表示期望收到下一个数据的序列号),同时服务器也为自己选择一个初始序列号(例如seq=y)。
服务器进入SYN_RCVD状态。
第三次握手(ACK):
客户端收到服务器的SYN+ACK报文段后,向服务器发送一个确认报文段。该报文段的ACK标志位设置为1,确认号为y+1,序列号为x+1(因为第一次握手的SYN消耗了一个序列号,所以第二次握手的确认报文段序列号为x+1,但注意:实际上第三次握手的序列号就是x+1,因为第一个SYN不携带数据但消耗一个序列号,所以客户端发送的第一个数据字节的序列号将是x+1)。
客户端进入ESTABLISHED状态,服务器收到这个确认后也进入ESTABLISHED状态。
此时,连接建立完成,双方可以开始传输数据。
为什么需要三次握手?
主要目的是防止已失效的连接请求报文段突然又传送到服务器,从而产生错误。通过三次握手,双方都能确认自己和对方的发送和接收能力正常,并且同步了初始序列号。
四次挥手(终止连接)
四次挥手用于安全地关闭TCP连接,确保数据能够完整传输。
第一次挥手(FIN):
客户端(或服务器)想要关闭连接时,发送一个TCP报文段,其中FIN标志位设置为1,序列号为之前传送数据的最后一个字节的序列号加1(假设为seq=u)。
发送方进入FIN_WAIT_1状态,表示没有数据要发送了。
第二次挥手(ACK):
接收方收到FIN报文段后,发送一个确认报文段,ACK标志位设置为1,确认号为u+1,序列号为v(v为接收方之前传送数据的最后一个字节的序列号加1)。
接收方进入CLOSE_WAIT状态,此时连接处于半关闭状态,即发送方已经没有数据要发送了,但接收方可能还有数据要发送。
发送方收到这个确认后,进入FIN_WAIT_2状态。
第三次挥手(FIN):
当接收方也没有数据要发送时,它发送一个FIN报文段,FIN标志位设置为1,序列号为w(可能在第二次挥手的序列号v之后又发送了一些数据,所以w可能大于v),确认号仍为u+1(因为发送方没有发送新的数据)。
接收方进入LAST_ACK状态,等待最后的确认。
第四次挥手(ACK):
发送方收到接收方的FIN报文段后,发送一个确认报文段,ACK标志位设置为1,确认号为w+1,序列号为u+1(因为第一次挥手的FIN消耗了一个序列号,所以确认报文段的序列号为u+1)。
发送方进入TIME_WAIT状态,等待2MSL(最长报文段寿命)时间后进入CLOSED状态。接收方收到确认后立即进入CLOSED状态。
为什么需要四次挥手?
因为TCP连接是全双工的,每个方向必须单独关闭。当一方发送FIN时,只表示它没有数据要发送了,但还可以接收数据。另一方可能还有数据要发送,所以先发送一个ACK确认FIN,等自己数据发送完后再发送FIN关闭自己这个方向的连接。因此,关闭连接需要四次交互。