TCP协议
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议
TCP收发数据流程
如何收发数据
- 分段发送:
可靠传输
在TCP协议中,任何时候、任何一方都可以主动发送数据给另一方
为了解决数据报丢失、数据报错乱等问题,TCP协议要求:接收方收到数据报后,必须对数据报进行确认!
seq
:表示这次数据报的序号ACK
:表示这次数据报是一个确认数据报,1表示确认序号有效,确认接受到消息ack
:表示期望下一次接收的数据报序号,之前的X段数据接收完成
发送方如果长时间没有收到确认数据报(ACK=1),则会判定丢失或者是错误,然后重发
连接的建立(三次握手)
TCP协议要实现数据的收发,必须要先建立连接
连接的本质其实就是双方各自开辟的一块儿内存空间,空间中主要是数据缓冲区和一些变量
连接建立的过程需要经过三次数据报传输,因此称之为三次握手,通俗的例子如下:
老王 给 老张 打电话
开始
老王:喂,说话能听见吗?
老张:能听见,我说话你能听见吗?
老王:能听见
结束
经过这么操作之后,就能确定是连通了,就可以做相关的事了,具体过程如下:
状态含义如下:
- CLOSED:关闭连接
- SYN-SENT:请求连接状态
- SYN-RCVD:等待确认状态
- ESTAB-LISHED:连接成功
标志位含义如下:
- SYN:发起一个新连接, 1 是
具体过程如下:
- 客户端给服务端发送一个TCP报文,SYN=1,表示要跟服务端建立连接,此时由于客户端不知到是否连接成功,状态从 CLOSED-> SYN-SENT
- 服务端收到了客户端的请求连接消息,确认数据有效,将ACK=1,SYN=1,发送给客户端,我接受到你的请求了。此时服务端不知道客户端是否能正确接受到自己发送信息,状态从CLOSED->SYN-RCVD,等待客户端给自己一个回应
- 客服端收到服务端的确认消息后,知道自己与服务端已经联系上了,再给服务端发送个确认消息,此时状态从 SYN-SENT -> ESTAB-LISHED
- 服务端收到客户端的确认消息后,也知道和客户端之间联系上了,此时状态从 SYN-RCVD -> ESTAB-LISHED
连接的销毁(四次挥手)
通俗的将就是挂电话
开始
老王:老张,我讲完了,挂了哈?
老张:稍等,我还没讲完
老张继续叭叭。。。此处省略一千个字
老张:好了,老王,我也讲完了
老王:ok
结束
状态含义如下:
- CLOSE-WAIT:等待关闭
- LAST-ACK:最后确认关闭状态
标志位含义如下:
- FIN:关闭一个连接, 1 是
具体过程如下:
- 客户端进程发出连接释放报文,并且停止发送数据,跟服务端说,我要关掉连接了。释放数据报文首部,FIN=1。此时,客户端进入FIN-WAIT-1(终止等待1)状态。
- 服务器收到连接释放报文,发出确认报文,ACK=1。此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
- 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
- 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
- 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
- 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
MSL(Maximum Segment Lifetime),报文最长存活时间
为什么需要等待2MSL?
保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。