tcp建立连接为什么要三次握手

tcp是一个面向连接的协议,在传送数据以前,必须要首先建立一条连接。连接的建立需要经过三次握手。为什么要经过三次握手呢,每次握手双方都做了些什么?

 

1)什么是tcp报文?

tcp报文就是通过tcp协议发送的数据包,由tcp头和数据段组成。

tcp头是固定的20个字节,它的格式为:

16位源端口号

16位目的端口号

32位序号

32位确认序号

4位首部长度

保留6

U

R

G

A

C

K

P

S

H

R

S

T

S

Y

N

F

I

N

16位窗口大小

16位校验和

16位紧急指针

         

 

2)第一次握手做什么?

请求端(客户端)会向服务端(被请求端)发送一个tcp报文,申请打开某一个端口。因为没有数据,所以这个报文仅包含一个tcp头。其中:

SYN=1;当建立一个新的连接时, SYN标志变1

序号;序号用来标识从客户端向服务端发送的数据字节流。 

此时客户端进入SYN_SENT状态。

 

3)第二次握手做什么?

服务端收到客户端的SYN包,也会发一个只包含tcp头的报文给客户端。

ACK=1;服务端确认收到信息

确认序号;客户端序号+1,作为应答

SYN=1;因为tcp的连接是双向的,服务端作为应答的同时请求建立连接。 

此时服务端进入SYN_RECV状态

 

4)第三次握手做什么?

ACK=1;客户端确认收到信息

确认序号;服务端序号+1,作为应答 

此时客户端进入ESTABLISHED状态,服务端收到ACK后也会进入此状态

 

可见,客户端和服务端都保留了对方的序号,这三次握手缺少任何一步都无法实现这一目标。在三次握手过程中,出现了一些中间状态。

 

5)什么是半连接队列?

第一次握手完成后,服务端发送ACK+SYN包到客户端,在收到客户端返回前的状态为SYN_RECV,服务端为此状态维护一个半连接队列。当服务端收到客户的确认包时,删除该条目,服务端进入ESTABLISHED状态。Listen中的backlog参数表示这两个状态合的最大值。若客户端完成第一次握手后不再发送ACK包,导致服务端未完成队列溢出,达到Dos攻击的目的。

 

6)什么是SYN-ACK 重传?

Dos攻击可以达到目的的一个重要因素是服务端在发送完SYN+ACK包后会等待客户端的确认包,如果等待时间内未收到,服务端会进行首次重传,等待一段时间仍未收到客户确认包,会进行第二次重传,直到重传次数超过系统规定的最大值,系统将该连接信息从半连接队列中删除。如果系统删除的频率小于半连接状态的增长频率,服务端就无法正常提供服务。 

 

7)Tcp关闭连接需要四次握手,这又是为什么呢?

这是由tcp半关闭(harf-close)造成的。既然一个TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。即一方发送一个FIN,另一方收到后发送一个ACK,这就是所谓的四次握手了。

 

8)第一次握手做什么?

客户端发送一个FIN(这个客户端是主动发起关闭的一端,与建立连接时的客户端不一定是同一主机)

此时客户端进入FIN_WAIT_1状态。

 

9)第二次握手做什么?

服务端收到FIN,发回客户端一个ACK,确认序号为收到的序号加1(因为FINSYN一样,会占用一个序号);客户端收到ACK之后会进入FIN_WAIT_2状态,服务端会进入CLOSE_WAIT状态。

 

10)第三次握手做什么?

服务端发送给客户端一个FIN。服务端进入LAST_ACK状态。

 

11)第四次握手做什么?

客户端收到FIN,发回服务端一个ACK,确认序号为收到的序号加1;客户端会进入TIME_WAIT状态,2MSL超时后进入CLOSE状态。服务端收到ACK后也会进入CLOSE状态。

 

其实我们通俗的说每次握手其实就是发一次数据包的过程。建立连接时双方共发送了3个包,关闭连接时发送和确认的两次握手决定了一端数据流的关闭,四次握手可以保证两方都关闭。

 

但由此引出一个问题,那就是

12)为什么建立连接是三次握手,而关闭连接是四次呢?

建立连接时,服务端可以把应答ACK和同步SYN放在一个报文里进行发送。而关闭连接时,收到FIN通知仅仅表示对方没有数据发送过来了,并不表示自己的数据全部发送给了对方。所以ACKFIN是分了两次进行发送。如果服务端收到FIN,恰恰自己也没有数据要发,是不是ACKFIN可以一起发给客户端呢,这样就可以少一次数据流了。世界是美好的,经典的TCP连接状态图中也考虑到了这种情况,tcp关闭连接确实是只有三次数据流动,服务端将ACKFIN放在一个包里进行发送,但四次握手这个概念却已经根深蒂固无法更改了。

 

13)Tcp的各个状态是怎样的?

客户端的正常tcp状态:

CLOSED->SYN_SENT(第1次)->ESTABLISHED(第3次)->FIN_WAIT_1(第1次)->FIN_WAIT_2(第2次)->TIME_WAIT(第4次)->CLOSED

 

服务端的正常tcp状态:

CLOSED->LISTEN->SYN_RCVD(第2次)->ESTABLISHED(第3次)->CLOSE_WAIT(第2次)->LAST_ACK(第3次)->CLOSED(第4次)

 

tcp还有其他的非正常状态,在此不做讨论,下篇文章再说

 

参考资料:

W.Richard Stevens著《TCPIP详解卷一》

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值