TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手。
1、连接的建立:
c端发起请求同步(用SYN段等于1的TCP报文),确认某个端口是否监听;
s端应答(用ACK段等于1的TCP报文),
c端收到s端的ACK,并回应s端一个ACK给s端;
经过上面三步连接的建立完成。这就叫做三次握手;
2、连接的中止:(TCP中有half-close,这是因为TCP的连接是全双工(可以同时发送和接收)连接,关闭的时候就需要在两个方向上都进行关闭,否则就是half-close)
c端发起关闭(FIN为1的TCP报文);
s端应答c端(用ACK段等于1的TCP报文);
上面两步完成就是半关闭(half-close)
s端发起关闭(FIN为1的TCP报文)
c端应答s端(用ACK段等于1的TCP报文)
经过上面四步,连接中止。这叫做四次挥手;
最大报文长度MSS
在建立连接的时候,通信的双方要互相确认对方的最大报文长度(MSS),以便通信。
一般这个MSS长度是MTU减去固定IP首部和TCP首部长度。对于一个以太网,一般可以达到1460字节。当然如果对于非本地的IP,这个MSS可能就只有536字节,而且,如果中间的传输网络的MSS更佳的小的话,这个值还会变得更小。
TCP的状态迁移图
TCP的状态图参见书P182页,这个图实在太精彩了(笔要偷懒,好好研究);
2MSL等待状态
TCP状态图中有一个TIME_WAIT等待状态,这个状态又叫做2MSL状态,说的是在TIME_WAIT2发送了最后一个ACK数据报以后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束,但是,问题也来了。
由于插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。
4.5.FIN_WAIT_2状态
这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态。