您的位置:首页 > 理论基础 > 计算机网络

TCP三次握手/四次挥手及其状态分析

2010-04-08 23:08 169 查看
前面CLOSE_WAIT状态分析与TIME_WAIT状态分析其实都是TCP断开连接过程中的两个状态.本文继续介绍下TCP连接三次握手,四次挥手的过程及其中间的状态

三次握手原理:

第一次握手:客户端发送syn包(syn=j)到服务器,等待服务器确认.

第二次握手:服务器收到syn包,必须确认(ack=j+1),同时自己发送一个syn包(syn=k),即SYN+ACK包.

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包(ack=k+1).

图示:

CLINET ----- SYN(j) ----- SERVER

SERVER ----- ACK(j+1) SYN(k) ----- CLINET

CLINET ----- ACK(k+1) ----- SERVER

客户端发送syn包,进入SYN_SEND状态,服务器收到sync包,进入SYN_RECV状态.

客户端收到服务器端的SYN+ACK包进入ESTABLISHED状态.

服务器端收到客户机端的ack包,进入ESTABLISHED状态.

简单的说:

客户端问服务器:你允许我和你建立连接么?

服务器端说:可以,那你也允许我和你建立连接么?

客户端说:可以.

于是,他们之间就建立起连接了.

四次分手原理:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭.这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接.收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据.首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭.

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送.

(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1.

(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A.

(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1.

图示:

CLINET --- FIN --- SERVER

SERVER --- ACK --- CLINET

SERVER --- FIN --- CLINET

CLINET --- ACK --- SERVER

客户端主动关闭连接,发送FIN包,进入FIN_WAIT_1状态.接收端收到FIN包,进入CLOSE_WAIT状态.

客户端收到服务器的ACK包,进入FIN_WAIT_2状态.

服务器发送FIN包,进入LAST_ACK状态.客户端接收到FIN包,进入TIME_WAIT状态

服务器收到ACK包,进入CLOSED状态.

简单的说:

客户端问服务器:我们断开连接吧?

服务器端说:可以,我将不再接收你的数据.

服务器端问服务器:我将要跟你断开连接了,可以吧?

客户端说:可以.

客户端说:可以.

于是,他们之间的连接就断开了.

TCP连接正常建立和终止过程及对应状态如图:

http://hi.csdn.net/space-4175647-do-album-picid-512430.html

这里有个连接同时打开的问题,跟前面文章中说的五元组问题一样,很难出现,但如果指定本地和对方两端的端口号还是能制造出这样的情况.

两端都是在SYN_SENT状态下收到对方的SYN包而进入SYN_RCVD状态,然后都会发送SYN+ACK包,当两端都会收到该包时,状态会变成ESTABLISHED.

图示:

CLINET --- SYN --- SERVER SERVER --- SYN --- CLINET

SERVER --- SYN+ACK --- CLINET CLINET --- SYN+ACK --- SERVER

TCP连接同时建立过程及对应状态如图:

http://hi.csdn.net/space-4175647-do-album-picid-512432.html

继续说下CLOSING状态,当两端几乎同时关闭连接时,两端都是在FIN_WAIT_1状态下收到对方的FIN包,会进入CLOSING状态.然后都会发送最后的ACK包.当两端都会收到该包时,状态会变成TIME_WAIT.

图示:

CLINET --- FIN --- SERVER SERVER --- FIN --- CLINET

SERVER --- ACK --- CLINET CLINET --- ACK --- SERVER

TCP连接同时关闭过程及对应状态如图:

http://hi.csdn.net/space-4175647-do-album-picid-512433.html

还有个问题:为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送.但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了.但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的.

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ustcgy/archive/2010/03/08/5356911.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: