TCP协议

122 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

今天考了计算机网络中有这么一题:发送端和接收端发送的报文分别是x和y然后balala我当时一看这有个D选项中an=y这不是妥妥的接收端返回的报文,an我以为是answer报文,后来才知道an是acknowledge number的缩写。现在借此机会好好回顾一下TCP的连接与断开,下次不再犯这样的小错误。

TCP的握手

我们知道要建立yigeTCP连接需要进行三次握手,通过三次握手之后才能建立可靠的连接服务。

在TCP的报文中有以下重要字段

  • 序号:seq序号,标识从TCP源向目的端发送字节流,并由发送端对其标记

  • 确认序号:ack序号,只有ACK标志位为1时确认序号字段才有效,ack=seq+1(注意:ack序号与ACK标志位不是同一个东西,还有的教材叫作an码这就是我被坑了的原因)

  • 注意:确认放ack=发起方req+1时两者配对成功

  • 标志位:共六个,即URG,ACK,PSH,RST,SYN,FIN

    • ACK:确认序号有效
    • PSH:接收方尽快将报文提交应用层
    • RST:连接重置
    • URG:紧急指针有效
    • SYN:发起一个新连接
    • FIN:释放一个链接

TCP三次握手是哪三次:

image.png

  • 第一次:客户端将标志位SYN设置为1,产生一个随机值seq=x并将其发送给server,等待server确认,自己进入SYN_SENT状态
  • 第二次:server收到数据包由SYN=1知道客户端建立请求,server将标志位SYNACK都设置为1,随机产生一个值seq=y,并将该数据发回客户端确认连接请求,server进入SYN_RCVD状态
  • 第三次:客户端收到确认后检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK设置为1ack=Ky1,并将数据包发给server,server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,客户端与服务端进入ESTABLISHED状态,完成三次握手,此后客户端与服务端即可开始传输数据了。

为啥要三次呢?两次不行吗?

为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了SYN=1创建连接的请求(第一次握手)。如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。客户端可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。

总结一句话就是为了防止建立无效的连接造成服务器性能的浪费。

TCP的四次挥手

image.png

  • 由于TCP连接是双全工的,每个方向都需要单独关闭,当一方发送数据完成后需要发送一个FIN来终止这一方向连接,收到FIN只是表示对方不会有数据流动了,但是接收方依然可以发送数据,直到接收方也发送了FIN
  • 第一次:客户端发送一个FIN,用来关闭客户端到服务端的数据传输,客户端进入FIN_WAIT_1状态
  • 第二次:服务端收到FIN后,发送一个ACK给客户端,确认序号为收到序号+1,服务端进入CLOSE_WAIT状态
  • 第三次:服务端向客户端发送一个FIN,用来关闭服务端到客户端的数据传输,服务端进入LAST_ACK状态
  • 第四次:客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务端,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次分手

为什么握手是三次,挥手却是四次呢?

因为服务端在LISTEN状态下,收到建立请求的SYN报文后,把ACKSYN都放在一个报文里发给了客户端。关闭连接时当收到对方的FIn报文仅仅表示对方不再发数据了,但还能接数据,自己也未必把所有数据发送给对方了,所以己方可以立即关闭也可以发送数据后再发送FIn报文给对方同意现在关闭,因此ACKFIN都会分开发送。