协议速查:你要知道的所有TCP协议的一切----理论篇

TCP是一种面向连接的、可靠的传输协议,通过三次握手建立连接,确保双方都能发送和接收数据。握手过程中,客户端发送SYN,服务器响应SYN+ACK,客户端再发送ACK确认。而四次挥手用于断开连接,因TCP是全双工,客户端发送FIN,服务器回ACK,然后服务器发送FIN,客户端回ACK,最后客户端等待一段时间确保数据传输完成才关闭连接。挥手比握手多一次是因为关闭连接时需要确认双方都已无数据传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、TCP的定义:

TCP全称为Transmission Control Protocol(传输控制协议),是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。

 

二、三次握手流程(TCP连接建立):

三次握手:服务端新建套接字,绑定地址信息后开始监听,进入LIATEN状态。客户端新建套接字绑定地址信息后调用connect,发送连接请求SYN,并进入SYN_SENT状态,等待服务器的确认。服务端一旦监听到连接请求,就会将连接放入内核等待队列中,并向客户端发送SYN和确认报文段ACK,进入SYN_RECD状态。客户端收到SYN+ACK报文后向服务端发送确认报文段ACK,并进入ESTABLISHED状态,开始读写数据。服务端一旦收到客户端的确认报文,就进入ESTABLISHED状态,就可以进行读写数据了。
Client:你听到我说话吗?    Server:我听到了,你到我说话吗?     Client:我也听到了。
  

三、四次挥手流程(TCP连接建立):


四次挥手:客户端主动调用close时,向服务端发送结束报文段FIN报,同时进入FIN_WAIT1状态;服务器会收到结束报文段FIN报,服务器返回确认报文段ACK并进入CLOSE_WAIT状态,此时如果服务端有数据要发送的话,客户端依然需要接收。客户端收到服务器对结束报文段的确认,就会进入到FIN_WAIT2状态,开始等待服务器的结束报文段;服务器端数据发送完毕后,当服务器真正调用close关闭连接时,会向客户端发送结束报文段FIN包,此时服务器进入LAST_ACK状态,等待最后一个ACK的带来;客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出送确认报文段ACK;服务器收到了对结束报文段确认的ACK,进入CLOSED状态,断开连接。而客户端要等待2MSL的时间,才会进入到CLOSED状态。
client:我理解你意思了,我要挂电话了。   服务端:好的。   服务端:那你挂吧。   客户端:好的。

为什么握手是三次,而不是两次或者四次?
答:两次不安全,四次没必要。tcp通信需要确保双方都具有数据收发的能力,得到ACK响应则认为对方具有数据收发的能力,因此双方都要发送SYN确保对方具有通信的能力。第一次握手是客户端发送SYN,服务端接收,服务端得出客户端的发送能力和服务端的接收能力都正常;第二次握手是服务端发送SYN+ACK,客户端接收,客户端得出客户端发送接收能力正常,服务端发送接收能力也都正常,但是此时服务器并不能确认客户端的接收能力是否正常;第三次握手客户端发送ACK,服务器接收,服务端才能得出客户端发送接收能力正常,服务端自己发送接收能力也都正常。

为什么握手是三次,而挥手时需要四次呢?
答:其实在TCP握手的时候,接收端将SYN包和ACK确认包合并到一个包中发送的,所以减少了一次包的发送。对于四次挥手,由于TCP是全双工通信,主动关闭方发送FIN请求不代表完全断开连接,只能表示主动关闭方不再发送数据了。而接收方可能还要发送数据,就不能立即关闭服务器端到客户端的数据通道,所以就不能将服务端的FIN包和对客户端的ACK包合并发送,只能先确认ACK,等服务器无需发送数据时在发送FIN包,所以四次挥手时需要四次数据包的交互

 

四、服务器/客户端的TCP监听状态:

 

客户端的连接状态有几种:
LISTEN,SYN-SENT,SYN-RECEIVED,ESTABLISHED,FIN_WAIT_1,FIN_WAIT_2,CLOSE_WAIT和TIME_WAIT,LAST-ACK和 CLOSED。

他们的含义要从TCP的连接与中断过程说起:

连接:
                                         Client    (三次握手)    Server
                                               --------SYN -------->
                                               <------- ACK/SYN -------
                                                 -------- ACK -------->


1.服务器侦听来自远方的TCP端口的连接请求,服务器处于LISTEN状态;
2.客户端首先向服务器发送SYN包,客户端处于SYN-SENT状态;
3.服务端接到第一次握手请求后,发送ACK包和SYN包,进行确认并请求第二次握手,服务端处于SYN-RECEIVED状态;
4.客户端发送ACK确认,进行第三次握手,两端均处于ESTABLISHED状态,可进行数据传输;

 

断开:
                                       Client     (四次断开)       Server                              
                                         -------- FIN -------->
                                        <------- ACK --------
                                        <------- FIN --------- 
                                         -------- ACK -------->

1.客户端首先向服务器发送FIN包,客户端进入FIN_WAIT_1状态;(客户端完成了数据的传输,而服务端没有完成)
2.服务端向客户端发送ACK,确认FIN包收到,服务端进入CLOSE_WAIT状态,客户端进入FIN_WAIT_2状态;
3.服务端等待他上面的应用程序关闭连接,一旦连接被关闭(服务端完成数据的传输),服务端进入LAST_ACK状态,会发送FIN包到客户端,客户端收到后进入TIME_WAIT状态,并发送最后一个ACK包,由于在连接关闭后,还不能确定所有连接关闭前的包(最后一个ACK包)被服务端收到了,可能由于网络不可靠的原因导致服务端没有收到ACK,服务端超时后会重新发送FIN包,所有客户端进入了TIME_WAIT状态,就是为了重发ACK包,一般这个状态保持时间为2*MSL,MSL指的是一个TCP包在网络中存在的最长时间,大概2*MSL=240(s)。而后进入CLOSED状态;
4.服务器收到最后一个ACK包后,进入CLOSED状态。

 

五、TCP包类型:

 

在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG.

1.SYN表示建立连接,
2.FIN表示关闭连接,
3.ACK表示响应,
4.PSH表示有 DATA数据传输,
5.RST表示连接重置。


几种场景:

1.如果只是单个的一个SYN,它表示的只是建立连接。

2.ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应,TCP的几次握手就是通过这样的ACK表现出来的。

3.PSH为1的情况,一般只出现在 DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。

4.RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。


一般地,当出现FIN包或RST包时,我们便认为客户端与服务器端断开了连接;而当出现SYN和SYN+ACK包时,我们认为客户端与服务器建立了一个连接。

 

FAQ:

三次握手可以携带数据吗?
答:第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的。假设第一次可以携带数据,如果有人恶意公鸡服务器,每次都在第一次我手中的SYN报文放入大量数据,重复发送大量SYN报文,此时服务器会花费大量内存空间来缓冲这些报文,服务器就更容易被攻击了

tcp三次握手失败,服务端会如何处理?
答:握手失败的原因有两种,第一种是服务端没有收到SYN,则什么都不做;第二种是服务端回复了SYN+ACK后,长时间没有收到ACK响应,则超时后就会发送RST重置连接报文,释放资源

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值