理解TCP的三次握手及四次分手

服务器 struggling 1663次浏览 1个评论

TCP是面向连接的协议,处在网络层的IP之上的传输层中,负责检测数据包是否被正确接收,或者会不会被接受。

下图是TCP与各封包之间的关系:

各封包之间的相关性
各封包之间的相关性
TCP 封包的表头是长这个样子的:

4 bits 6 bits 6 bits 8 bits 8 bits
Source Port Destination Port
Sequence Number
Acknowledge Number
Data
Offset
Reserved Code Window
Checksum Urgent Pointer
Options Padding
Data

TCP 封包的表头资料

上图就是一个 TCP 封包的表头数据,各个项目以 Source Port, Destination Port 及 Code 算是比较重要的项目,底下我们就分别来谈一谈各个表头数据的内容吧!

Source Port & Destination Port (来源埠口 & 目标端口)

什么是埠口(port)?我们知道 IP 封包的传送主要是藉由 IP 地址连接两端, 但是到底这个联机的通道是连接到哪里去呢?没错!就是连接到 port 上头啦! 举例来说,鸟哥的网站有开放 WWW 服务器,这表示鸟站的主机必须要启动一个可以让 client 端连接的端口,这个端口就是 port (中文翻译成为埠口)。同样的,客户端想要连接到鸟哥的鸟站时,就必须要在 client 主机上面启动一个 port ,这样这两个主机才能够利用这条『通道』来传递封包数据喔!这个目标与来源 port 的纪录,可以说是 TCP 封包上最重要的参数了!

Sequence Number (封包序号)

由于 TCP 封包必须要带入 IP 封包当中,所以如果 TCP 数据太大时(大于 IP 封包的容许程度), 就得要进行分段。这个 Sequence Number 就是记录每个封包的序号,可以让收受端重新将 TCP 的数据组合起来。

Acknowledge Number (回应序号)

为了确认主机端确实有收到我们 client 端所送出的封包数据,我们 client 端当然希望能够收到主机方面的响应,那就是这个 Acknowledge Number 的用途了。 当 client 端收到这个确认码时,就能够确定之前传递的封包已经被正确的收下了。

Data Offset (资料补偿)

在图 2.4-2 倒数第二行有个 Options 字段对吧!那个 Options 的字段长度是非固定的,而为了要确认整个 TCP 封包的大小,就需要这个标志来说明整个封包区段的起始位置。

Reserved (保留)

未使用的保留字段。

Code (Control Flag, 控制标志码)

当我们在进行网络联机的时候,必须要说明这个联机的状态,好让接收端了解这个封包的主要动作。 这可是一个非常重要的句柄喔!这个字段共有 6 个 bits ,分别代表 6 个句柄,若为 1 则为启动。分别说明如下:

URG(Urgent):

若为 1 则代表该封包为紧急封包, 接收端应该要紧急处理,且图 2.4-1 当中的 Urgent Pointer 字段也会被启用。

ACK(Acknowledge):

若为 1 代表这个封包为响应封包, 则与上面提到的 Acknowledge Number 有关。

PSH(Push function):

若为 1 时,代表要求对方立即传送缓冲区内的其他对应封包,而无须等待缓冲区满了才送。

RST(Reset):

如果 RST 为 1 的时候,表示联机会被马上结束,而无需等待终止确认手续。这也就是说, 这是个强制结束的联机,且发送端已断线。

SYN(Synchronous):

若为 1,表示发送端希望双方建立同步处理, 也就是要求建立联机。通常带有 SYN 标志的封包表示『主动』要连接到对方的意思。

FIN(Finish):

若为 1 ,表示传送结束,所以通知对方数据传毕, 是否同意断线,只是发送者还在等待对方的响应而已。

其实每个项目都很重要,不过我们这里仅对 ACK/SYN 有兴趣而已,这样未来在谈到防火墙的时候,你才会比较清楚为啥每个 TCP 封包都有所谓的『状态』条件!那就是因为联机方向的不同所致啊!底下我们会进一步讨论喔! 至于其他的数据,就得请您自行查询网络相关书籍了!

Window (滑动窗口)

主要是用来控制封包的流量的,可以告知对方目前本身有的缓冲器容量(Receive Buffer) 还可以接收封包。当 Window=0 时,代表缓冲器已经额满,所以应该要暂停传输数据。 Window 的单位是 byte。

Checksum(确认检查码)

当数据要由发送端送出前,会进行一个检验的动作,并将该动作的检验值标注在这个字段上; 而接收者收到这个封包之后,会再次的对封包进行验证,并且比对原发送的 Checksum 值是否相符,如果相符就接受,若不符就会假设该封包已经损毁,进而要求对方重新发送此封包!

Urgent Pointer(紧急资料)

这个字段是在 Code 字段内的 URG = 1 时才会产生作用。可以告知紧急数据所在的位置。

Options(任意资料)

目前此字段仅应用于表示接收端可以接收的最大数据区段容量,若此字段不使用, 表示可以使用任意资料区段的大小。这个字段较少使用。

Padding(补足字段)

如同 IP 封包需要有固定的 32bits 表头一样, Options 由于字段为非固定, 所以也需要 Padding 字段来加以补齐才行。同样也是 32 bits 的整数。

理解了TCP数据包的表头信息后,我们就来看TCP的三次握手及四次分手是怎样完成的,以下是 TCP三次握手的模型图:

tcp三次握手

当客户端A要与服务器B建立连接时,TCP的有限状态机由closed状态变为SYN_SENT状态,A发起主动连接请求,发送ACK=0,SYN=1的标志码的数据包,
服务器端此时得监听客户端的状态,所以服务器端被动打开,由以前的closed状态变为Listen状态,并且发送SYN=1,ACK=1,标志码的数据包,表示已经响应请求了,
然后服务器端的状态变为SYN_RECD,等待客户端的响应,客户端接收后,此时服务器端的状态就变为ESTABLISHED,就表示两者已经建立连接了。

下图为TCP四次分手的状态变化图:

四次分手

当客户端要求段开连接时,此时会发送带有FIN为1的数据包,发送后状态会变为TIME_WAIT,
服务器端接受客户端的请求后,后发送一个响应数据包,然后状态由ESTABLISHED状态变为CLOSED_WAIT状态,此时服务器端应经响应了,
客户端收到想应数据包后会继续等待服务器端与自己段开连接 ,客户端的状态会变为TIME_WAIT2,
服务器端然后会再发送一个带有FIN为1的数据包给客户端,表示服务器端也要与客户端段开连接,此时服务器端的状态会变为LAST_ACK,
此时客户端收到断开请求时,会发送一个响应数据包给服务器端,但是服务器断不会去响应,要不然会循环下去。
但是服务器端会不会收到此数据包呢?
为了使服务器端会受到响应数据包,客户端设置此数据包的丢弃时间为2*MSL时长,大概为240sec,以确保数据包能完整的到达服务器端。

下图为TCP各种状态之间的转换图,绿色为客户端之间的状态转化路线,红色虚线为服务器端的转换路线:

tcp有限状态机


DevOps-田飞雨 》》转载请注明源地址
喜欢 (1)or分享 (0)
发表我的评论
取消评论
*

表情 贴图 加粗 链接 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽
  1. 好文章,内容文从字顺.禁止此消息:nolinkok@163.com
    荷兰网2015-06-29 19:40 回复