理解TCP的三次握手和四次挥手
OSI
7层网络模型
OSI是
Open System Interconnection
的缩写,国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。
参考模型(从上至下) | 各层含义 |
---|---|
应用层 | 为应用程序提供给服务,如HTTP,FTP,SMTP,POP3 等 |
表示层 | 数据格式转换翻译、数据加密解密、压缩解压缩 |
会话层 | 不同机器之间的用户建立及管理会话 |
传输层 | 建立管理和维护端到端的连接,TCP,UDP |
网络层 | IP 地址及路由选择 |
数据链路层 | 物理寻址,将原始比特流转化到逻辑传输线路 |
物理层 | 机械、电子、定时接口通信信道上的原始比特流传输 |
1.传输层
接受上一次的数据,将数据进行分割,保证数据准确到达对端。
2.TCP
TCP
是面向连接的无状态的协议。为了连接的可靠性,每次连接的建立都需要3次握手。
1.建立连接(3次握手)
3次握手的目的:
- 同步连接对方的序列号和确认号;
- 交换
TCP
窗口大小的信息。
客户端(状态) | 建立连接(三次握手) | 服务端(状态) |
---|---|---|
CLOSED | LISTEN | |
SYN seq=0 ==> | ||
SYN_SEND | ||
<== SYN ACK ack=1,seq=0 | ||
SYN_RCVD | ||
ACK ack=1,seq=1 ==> | ||
ESTABLISHED | ESTABLISHED |
- 第一次握手:建立连接。客户端发送连接请求,发送
SYN
报文,随机生成seq
,本例默认为0
。然后,客户端进入SYN_SEND
状态,等待服务器的确认。 - 第二次握手:服务器收到客户端的
SYN
报文段。需要对这个SYN
报文段进行确认,发送ACK
报文,将ack
设置为1
(ack
的值为对方seq+1
或者seq+L
(数据长度L))。同时,自己还要发送SYN
请求信息,将seq
置为0
。服务端将上述所有信息一并发送给客户端,此时服务器进入SYN_RECV
状态。 - 第三次握手:客户端收到服务器的
ACK
和SYN
报文后,进行确认,然后将ack
设置为1
,seq
设置为1
,向服务器发送ACK
报文段,这个报文段发送完毕以后,客户端和服务端都进入ESTABLISHED
状态,完成TCP
三次握手。
2.数据传输
客户端 | 数据传输 | 服务端 |
---|---|---|
PSH seq=1,ACK ack=1(segmentLen = 99) ==> | ||
<== PSH seq=1,ACK ack=100(segmentLen = 119) | ||
ACK ack=120,seq=100 ==> |
- 客户端先向服务器发送数据,该数据报是长度为99的数据。
- 服务器收到该报文后,也向客户端发送了一个数据进行确认(
ACK
),并且返回客户端要请求的数据,数据的长度为111
,将seq
设置为1
,ack
设置为120(1 + 119)
。 - 客户端收到服务器返回的数据后进行确认(
ACK
),将seq
设置为100
,ack
设置为112(1 + 111)
。
3.断开连接(4次挥手)
客户端(状态) | 断开连接 | 服务端(状态) |
---|---|---|
FIN ACK ack=120,seq=100 ==> | ||
FIN_WAIT_1 | ||
<== ACK ack=101,seq=120 | ||
FIN_WAIT_2 | CLOSE_WAIT | |
<== ACK ack=101,seq=120 | ||
LAST_ACK | ||
ACK ack=121,seq=101 ==> | ||
TIME_WAIT | CLOSE |
- 第一次挥手:客户端向服务器发送一个
FIN
报文段,将设置seq
为100
和ack
为120
,;此时,客户端进入FIN_WAIT_1
状态,这表示客户端没有数据要发送服务器了,请求关闭连接; - 第二次挥手:服务器收到了客户端发送的
FIN
报文段,向客户端回一个ACK
报文段,ack
设置为101
,seq
设置为120;服务器进入了CLOSE_WAIT
状态,客户端收到服务器返回的ACK
报文后,进入FIN_WAIT_2
状态; - 第三次挥手:服务器会观察自己是否还有数据没有发送给客户端,如果有,先把数据发送给客户端,再发送FIN报文;如果没有,那么服务器直接发送
FIN
报文给客户端。请求关闭连接,同时服务器进入LAST_ACK
状态; - 第四次挥手:客户端收到服务器发送的
FIN
报文段,向服务器发送ACK
报文段,将seq
设置为101
,将ack
设置为121
,然后客户端进入TIME_WAIT
状态;服务器收到客户端的ACK
报文段以后,就关闭连接;此时,客户端等待2MSL
后依然没有收到回复,则证明Server
端已正常关闭,客户端也可以关闭连接了。
计算规则: seq 为序列号 ack 为应答码 seq = 对方上次的ack;(首次发送时seq为系统随机生成) ack = 对方的seq+1(无数据传输时) 或者 seq+L(报文数据的长度L)