一、TCP协议的作用:
TCP是介于IP层和应用层中间的部分, 用来在两台机器能找到对方的前提下, 定位到底是机器上哪些进程在进行通信(通过进程使用端口的方式)。
按之前的图, TCP 的包里面的数据部分包裹了应用层的包,自己又被包裹在IP包的数据部分。
二、TCP如何解决丢包问题
每次发送端发送一个数据的时候,都会有一个 ack 编号,接收方在接收到数据之后, 必须要回复一个跟这个ack关联的应答包。
每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。举例来说,现在收到了4号包,但是没有收到5号包。ACK 就会记录,期待收到5号包。过了一段时间,5号包收到了,那么下一轮 ACK 会更新编号。如果5号包还是没收到,但是收到了6号包或7号包,那么 ACK 里面的编号不会变化,总是显示5号包。这会导致大量重复内容的 ACK。如果发送方发现收到三个连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即5号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。
也就是说主要通过【应答包超时】和【发现收到的应答包是三个连续的重复 ACK】来确定包是否丢失,丢失了则重传。
三、TCP的连接方式:
三次握手四次挥手过程如下 :
为了便于理解,我们可以思考下为什么要进行三次握手?
主要是初始化资源和告诉对方我的序列化(为后面的数据传输做准备工作)。
所以三次握手的次序是这样子的:
1)client端首先发送一个SYN包告诉Server端我的初始序列号是X;
2)Server端收到SYN包后回复给client一个ACK确认包,告诉client说我收到了;
3)接着Server端也需要告诉client端自己的初始序列号,于是Server也发送一个SYN包告诉client我的初始序列号是Y;
4)Client收到后,回复Server一个ACK确认包说我知道了。
其中的 2 、3 步骤可以简化为一步,也就是说将 ACK 确认包和 SYN 序列化包一同发送给 Client 端。到此我们就比较简单的解释了 TCP 建立连接的“三次握手”。
那么四次挥手呢?为什么要四次?(参考https://www.jianshu.com/p/7ddb0e7867ac)
首先我们需要关注的一点是【TCP的连接是全双工的】,所以在断开连接的时候,通信双方都要告知对方自己不再发送数据(也可以认为拆除两条通道)。
第一次挥手表示客户端不再发送数据给服务端,
第二次挥手表示服务端发送ack应答包,收到了客户端的请求,
此时客户端不可以再给服务端发送数据,但是服务端还是可以给客户端发送数据的,客户端也可以读取到(这条通道还没有关闭)。这个状态叫做半关闭状态。
第三次挥手表示服务端不再给客户端发送消息,
第四次挥手为客户端发送给服务端的ack应答包。
四次挥手里面,最经典的场景,是Client处于TIME_WAIT之后的2MSL的时间处理。(备注:MSL是TCP报文里面最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。) 设置2MSL的目的是为了处理,Server端在重传最后一个FIN的时候,Client能够发送最后一个ACK的时间。 这个时间段内,不管是Client端还是Server端,最好都不要重用这个TCP的端口,否则的话,可能会导致根据这个端口新建立的连接被错误的关掉。