相关概念
SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用。当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来端口扫描。扫描者只发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来,就表明这台主机存在这个端口。但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描成功表示被扫描机器不安全,一台安全的主机会强制要求一个连接严格的进行TCP的三次握手。
ACK:代表报文到达确认,是对接收到的数据的最高序列号的确认,并向发送端返回一个下次接收时期望的TCP数据包的序列号。如发送方发送了100字节数据,那么接收方回将ACK置为101,代表希望的到100之后的数据,然后回复给发送方。
FIN:表示发送端已经到达数据末尾,也就是说双方的数据传输完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
-
SEQ:表示这个包中第一个字节的序号。如已经发送了100字节的数据,要再发送10字节,那么再次发送的包的SEQ就是101,数据的字节编号是101到110,之后再次发送的话SEQ就是111。
如果接收端收到这个10字节的包的话,便会返回一个ACK为111的包。表示前面110个字节已经成功接收。
三次握手
TCP的3次握手本质是信道不可靠,但是通信双方需要就某个问题达成一致。而要解决这个问题,无论在消息中包含什么信息,三次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足在不可靠信道上传输可靠消息这一需求所导致的。如果信道可靠,或并不关心数据对方是否可以收到,那么三次握手就没有必要。
-
第一次握手:建立连接。客户端发送请求报文,将SYN置为1,SEQ为x(系统动态随机取一个32位长的序列号),然后客户端进入SYN_SEND状态,等待服务端确认。
理解: SYN=1,代表将要发起一个请求。SEQ=x,是一个随机数。代表序号的初始值,之后的序号在此值之上累加
-
第二次握手:服务端收到SYN报文。对SYN报文进行确认,设置ACK为x+1。同时也发送一个SYN请求。将SYN置为1,SEQ为y(系统动态随机取一个32位长的序列号)。服务端将上述所有信息发送给客户端,同时也进入SYN_RECV状态。
理解:服务器接收到SYN=1的请求,由于SEQ(序列号为)x,那么需要告诉客户端需要x后面的数据,所以ACK+1也就是x+1。同时服务端也要发起一个请求和客户端建立连接,所以再设置一个SEQ(序列号)=y(初始随机值)。然后将上述内容发送给客户端
-
第三次握手:客户端收到服务端的报文。将ACK置为y+1。向服务端发送ACK报文段。发送完成后,客户端和服务端都进入ESTABLISHED状态,完成TCP三次握手
理解:客户端收到服务端消息,由于服务端发起了连接请求,需要将ACK设置为服务端的SEQ(序列号)+1,也就是y+1,告诉服务端下次发送时,从y+1开始
四次挥手
四次挥手是因为虽然主机1(可以是客户端也可以是服务端)没有信息发送给主机2了,但是不代表主机2没有信息发送给主机1,所以主机2首先要返回一个报文,表示知道主机1没有数据发送了,同时检查自己是否还有数据发送,并处理完后。再向主机1发起断开连接请求。
- 第一次分手:主机1设置SEQ和ACK,向主机2发送一个FIN报文,此时主机1进入FIN_WAIT_1状态,表示主机1没有数据要发送给主机2了
- 第二次分手:主机2收到主机1发来的FIN报文,向主机1回复一个ACK报文。主机1进入FIN_WAIT_2状态,主机2告诉主机1,同意你的请求
- 第三次分手:主机2向主机1发送FIN报文,请求关闭连接。同时主机2进入LAST_ACK状态
- 第四次分手:主机1收到主机2的FIN报文,向主机2发送ACK报文,然后主机1进入TIME_WAIT状态,主机2收到主机1的ACK报文以后,就关闭连接。此时主机1等待2MSL(报文最大生存时间)后依然没有收到回复,则证明主机2连接已经正常关闭,那么主机1也断开连接。