TCP的连接建立
TCP运输连接有以下三个阶段:
- 建立TCP连接
- 数据传送
- 释放TCP连接
三报文握手
一开始,两端的TCP进程都处于关闭状态。
然后,TCP服务器首先创建传输控制块,用来存储控制块的信息,例如TCP连接表……
之后,TCP服务器就进去监听状态,等待TCP客服的连接请求。
- TCP发送连接请求,并将自己的状态改为同步已发送状态。
SYN设置为1,表示这是1个连接请求报文。
seq设置为x,作为TCP客服所选择的初始序号。
(TCP规定SYN设置为1的报文段不能携带数据但要消耗掉一个序号)
- 如果TCP服务器同意连接,则向TCP客户端发送一个针对连接请求的确认。
SYN和ACK设置为1,表明这是一个连接请求确认报文段。
seq设置为y,是TCP客户端的初始序号。
== ack为x+1(这是对TCP客户进程所选择的初始序号的确认)==
ack总是上一个seq的值加1
- TCP客户端在收到服务器端的连接请求报文段后,还要向服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态。(即发送一个连接请求确认的确认)
该报文段ACK=1,表示是一个连接确认。seq设置为x+1,是第一个序号x加一个,(消耗一个序号),ack=y+1表示是对上一个seq的确认。
整个过程就是
-
客户端:我喜欢你
-
服务器端:我也喜欢你
-
客户端:那我们在一起吧
-
本来都处于关闭状态,但是服务器知道客户端可能喜欢它,所以一直在等,处于一个监听状态。
-
然后客户端就说我喜欢你,说完自己处于同步发送状态。
-
然后服务器接收后也发了我喜欢你,然后表示已接收,处于同步接收状态。
-
然后客户端收到后,觉得事情成了,就发送我们在一起吧,然后自己就处于连接状态了。
-
然后服务器收到我们在一起吧后也懂了,也处于连接状态。
为什么TCP最后还要发送一个连接请求确认的确认呢?这是否多余?
答案肯定是不多余。
假若是两报文握手
假设TCP客户端发送一个连接请求,但是却因为某些原因在网络中滞留了,这必将造成超时重传。
于是乎就重传了一个TCP连接请求。
然后服务器收到后,就发送一个TCP连接请求的确认,并进入连接已建立状态。(因为是两报文握手,所以直接连接已建立,而不是同步已接收状态)
然后向客户端发送一个确认连接的请求,TCP客户端接收到后进入连接已建立状态。
此时可以进行数据传输。然后数据传输完毕后就通过“四报文挥手”来释放连接。
此时TCP双方都进入关闭状态,一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段到达了TCP服务器,此时TCP服务器进入连接已建立状态,并给TCP客户端发送来连接请求,并进入连接已建立状态。
该报文段进入TCP客户端,但TCP客户端仍为关闭转台,不会理睬。
但TCP服务已建立连接状态,它会一直等待客户端发送数据,所以会消耗很多资源。
四报文挥手
1.FIN=1和ACK=1表示是一个终止连接报文,
seq设置为u,它等于TCP客户进程之前已传送过 的数据的最后一个字节的序号加1。
确认号ack的序号为v,它等于TCP客户进程之前已收到的数据的最后一个字节的序号加1。
2.TCP服务器收到一个连接释放后,会弗萨松一个普通确认报文。并处于关闭等待状态。
seq为上一个ack,而ack为上一个seq+1;
然后TCP服务器通知上层的应用进程说TCP客户端要与自己断开连接,此时TCP服务端到TCP服务器这个进程就断了。
- 所以第一个过程就是客户端告诉服务器自己想跟它分手,以后不会再主动找它了,然后服务器确认了客户端以后不再找它的请求。
此时连接处于半关闭状态,也就是客户端不再主动找服务器。但是服务器想找客户端还是可以的。
(服务器给客户端发送数据,客户端还是得接收)
- 第二个过程就是服务器也告诉客户端我以后也不主动找你了,然后客户端答应了服务器,于是两人就都进入关闭状态,从此不再往来。
但是TCP客户端也知道肯定要完全诀别了。
于是进入一个终止等待状态2,等待TCP服务器最后还有没有话想说。
如果服务器已经无话想说了,TCP服务器就会发起一个连接释放报文段并进去最后确认状态。
FIN和ACK的值为1,表示这是一个连接释放报文,seq是重新是上次接收数据号加1。
而ack=上次反方向传输的seq=u +1。
为什么需要一个时间等待呢?
是怕客户端发送最终确认的过程中数据报丢了,这时候服务器会超时重传。
为了使客户端不是立刻处于关闭状态(还能接收到超时重传的数据报文),所以设置一个时间等待状态,确保能服务器和客户端都能接收到最后确认。
而且可以使本次连接持续时间内所产生的所有报文段从网络中消失,从而使下一个新的TCP连接中没有旧的报文段。
TCP的保活措施
如何客户端出现了故障,无法再给服务器发送数据,就应该有措施让服务器知道,而不是让服务器白白地等待下去。