网络编程之TCP三次握手,四次断开
TCP三次握手
1:上图的名词解释
- SYN:同步序号。
它表示建立连接
。TCP规定SYN=1时不能携带数据,但要消耗一个序号, 因此随机选取一个序列号为seq=x 数据包(该数据包里就是一个标记seq,并没有任何有效的数据) - ACK:确认序号。
它表示响应
(都能响应了 那肯定上一步就连接成功了啊,所以说ACK=1代表确认连接成功啦)
因此,SYN和ACK同时为1,表示建立连接之后的响应;而只是单个的SYN=1,表示的只是建立连接
- seq: (sequence number) 序列号。它是发送端数据包的初始序号。
seq=x 表示发送端数据包的初始序号为x
(seq = 0 就代表这是第0号帧) - ack:(acknowledge number) 确认号。它是对这次收到数据包的确认,以及对下次收到数据包的期待。
ack=x+1表示 我方 到 x为止的所有数据都已正确收到,且我方告知 对方:我期待你下次给我发送包的初始序号(seq)是x+1
为了方便记忆,可以这么理解:SYN/ACK是TCP协议层面的标记,而seq/ack是数据层面的标记
2:TCP三次握手过程
- 首先Client向Server发送连接:SYN = 1,seq = x;
因为
要建立连接,所以SYN=1
;又因为
TCP规定SYN=1时不能携带数据,但要消耗一个序号,所以
Client随机选取一个初始序号seq=x
。(因为并没有响应动作,所以这里没ACK什么事,我们就认为ACK=0吧)- 发送后Client进入syn_sent状态,表示客户端等待服务器的回复。
- Server收到请求后 再向Client发送确认:SYN=1, ACK=1, seq=y, ack=x+1;
- 因为Server建立连接后做出了响应,所以SYN=1, ACK=1。因为TCP规定SYN=1时不能携带数据,但要消耗一个序号, 所以Server随机选取一个初始序号seq=y。又因为Server到 x为止的所有数据都已正确收到了,且Server告诉Client:我期待你下次给我发送包的初始序号(seq)是x+1,所以ack=x+1
- 发送后服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待Client的确认。
- Client收到确认后还需再次发送确认,同时携带要发送给Server的数据:ACK=1, seq=x+1, ack= y+1;连接建立
- 因为有 响应 动作,所以ACK=1(因为要携带发送的数据,所以这儿没SYN什么事)。因为(2)中Server 已经告诉了这次它想收到包的初始序列号是x+1,所以初始序号为seq=x+1。又因为Client到 y为止的所有数据都已正确收到了,准备接收序列号为y+1的包,所以ack=y+1
- Server收到后,这个TCP连接就进入Established状态,就可以发起http请求了。
3:为什么不能改成两次握手?
有人会困惑为什么要进行三次握手呢(两次确认)?这主要是为了防止已失效的请求连接报文忽然又传送到了,从而产生错误。
假定A向B发送一个连接请求,由于一些原因,导致A发出的连接请求在一个网络节点逗留了比较多的时间。此时A会将此连接请求作为无效处理 又重新向B发起了一次新的连接请求,B正常收到此连接请求后建立了连接,数据传输完成后释放了连接。如果此时A发出的第一次请求又到达了B,B会以为A又发起了一次连接请求,如果是两次握手:此时连接就建立了,B会一直等待A发送数据,从而白白浪费B的资源。 如果是三次握手:由于A没有发起连接请求,也就不会理会B的连接响应,B没有收到A的确认连接,就会关闭掉本次连接