- TCP是面向连接的协议,它基于运输连接来传送TCP报文段。
- TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。
- TCP运输连接有以下三个阶段:
- 建立TCP连接
- 数据传送
- 释放连接
TCP的运输连接管理就是使运输连接的建立和释放都能正常地进行。
TCP连接的建立
TCP连接的建立要解决以下三个问题:
- 使TCP双方能够确知对方的存在;
- 使TCp双方能够协商一些参数(窗口最大值,是否使用窗口扩大选项和时间戳选项以及服务质量等)
- 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
- TCP使用”三报文握手”建立连接
两台要基于TCP进行通信的主机,其中一台中的某个应用进程主动发起TCP连接建立,称为TCP客户。另一台主机中被动等待TCP连接建立的应用进程,称为TCP服务器。我们可以将TCP建立连接的过程比喻为“握手”。握手需要在TCP客户和服务器之间交换三个TCP报文段。
- 最初两端TCP进程都处于关闭状态。
- TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息:
之后就准备接收TCP客户进程的连接请求,此时TCP服务器进程就进入监听状态。
- TCP服务器进程是被动等待来自TCP客户进程的连接请求而不是主动发起,因此称为被动打开连接
- TCP客户进程也是首先创建传输控制块:
- 然后,在建立TCP连接时,向TCp服务器进程发送TCP连接请求报文段,并进入同步已发送状态:
- TCP连接请求报文段首部中的同步位SYN被设置为1,表明这是一个TCP连接请求报文段,序号字段seq被设置了一个初始值x,作为TCP客户进程所选择的初始序号。TCP规定SYN被设置为1的报文段不能携带数据。但要消耗掉一个序号。
- 因为TCP连接建立是由TCP客户主动发起的,因此称为主动打开连接。
- TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态,该报文段首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文,序号字段被设置了一个初始值y,作为TCP服务器进程所选择的初始序号。确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号的确认。注意:这个报文段,也不能携带任何数据,但同样要消耗掉一个序号。
- TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态,该报文首部中的确认位ACK被设置为1,表明这是一个普通的TCP确认报文段,序号字段被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x。普通的确认报文段可以携带数据如果不携带数据,则不消耗序号,确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认,TCP服务器进程收到该确认报文段后也进入连接已建立状态。
- 双方都进入了连接已建立状态。他们可以基于已建立好的TCP连接,进行可靠的数据传输了。
- TCP客户进程发送的普通TCP确认报文是否多余,能不能两报文握手?
不多余。这是为了防止已失效的连接请求报文段突然又传送到了TCP服务器,因而导致错误。
假如采用两次握手:
TCP客户进程给TCP服务器发送连接请求,结果这个请求报文滞留在了网路中,TCP客户进程重发了一下TCP连接请求,TCP服务器进程收到后,发回TCP连接请求的确认,并进入连接已建立状态,TCP客户进程收到确认后,也进入连接已建立状态,然后双方开始数据传输,最后释放连接。
结果这时候当初滞留在网络中的失效的连接请求发到了TCP服务器进程上,TCP服务器进程又发了确认,然后直接进入连接已建立状态。但是这时候TCP客户进程是不会理睬的,TCP服务器进程会一直等待,浪费资源。
TCP连接的释放
- TCP通过”四报文挥手”来释放连接
- TCP客户进程与TCP服务器进程都处于连接已建立状态。
- TCP客户进程的应用进程通知其主动关闭TCP连接
- TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态。该报文首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认。同时序号seq字段的值设置位u,等于TCP客户进程之前已传送过的、数据的最后一个字节的序号加1.TCP规定,终止位FIN等于1的报文段即使不携带数据,也要消耗一个序号。确认号ack字段的值设为v,等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1.
- TCP服务进程收到TCP连接释放报文后,会发送TCP普通确认报文,确认位ACK的值位1,表明这是一个普通的TCP确认报文段,seq的值为v,等于TCP服务器进程之前已传送过的数据的最后一个序号加1,ack字段的值为u+1,这是对TCP连接释放报文段的确认。这时TCP服务器进程应通知高层应用进程:TCP客户进程要断开与自己的TCP连接。
- 此时从TCP客户进程到TCP服务器进程这个方向的连接就释放了,这时TCP连接属于半关闭状态:也就是TCP客户进程已经没有数据要发送了,但是TCP服务器进程如果还有数据要发送,TCP客户进程仍要接收。
- TCP客户进程收到TCP确认报文段后,就进入终止等待2状态。等待TCP服务器进程发出的TCP连接释放报文段。若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程就通知其服务器进程释放连接。由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接。
- TCP服务器进程发送TCP连接释放报文段并进入最后确认状态。该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这时一个TCP连接释放报文段,同时也对之前收到的报文段进行确认,假定seq的值为w,这时因为在半关闭的状态下,TCP服务器进程可能又发送了一些数据。确认号ack字段的值为u+1,这时对之前TCP连接释放报文段的重复确认。
- TCP客户进程收到TCP连接释放报文后,必须针对该报文段发送普通TCP确认报文段,之后进入时间等待状态。该确认报文段首部中的确认位ACK的值被设置为1,表明这时一个普通的TCP确认报文段,序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号。确认号ack的值设置为w+1。
- TCP服务器进程收到该报文段后就进入关闭状态。而TCP客户进程还要经过2MSL后才能进入关闭状态。
- MSL意思是最长报文段寿命,RFC793建议为2分钟。可以使用更小的MSL值
- TCP客户进程发送完最后一个确认报文段后,为什么不直接进入关闭状态,而是要进入时间等待状态,是否有必要:
看这样一种情况:
- TCP客户进程收到TCP服务器进程发送的TCO连接释放报文后,发送完TCP普通确认报文就直接进入关闭状态。
- 这个TCP普通确认报文丢失了,这就会造成TCP服务器进程对之前发送的TCP连接释放报文的超时重传,并仍处于最后确认状态。
- 重传的TCP连接释放报文段到达TCP客户进程,由于TCP客户进程处于关闭状态,因此不理睬该报文段,所以TCP服务器进程反复重传TCP连接释放报文段。并一直处于最后确认状态。
- 2MSL可确保TCP服务器进程收到最后一个TCP确认报文段而进入关闭状态。
保活计时器
TCP双方建立连接后,客户进程一方出现故障,这时TCP服务器进程就不能再收到TCP客户进程发来的数据。因此应有措施使TCP服务器进程不要再白白等待下去。
- TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)。
- 若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就像TCP客户进程发送一个探测报文段,以后每个75秒钟发送一次。若一连发送10个探测报文后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。