TCP协议是一种面向连接的、可靠的流协议。
流即不间断的数据结构。这样能够保证接收到数据顺序与发送相同。但是犹如数据间没有间隔,因此在TCP通信中,发送端应用可以在自己所要发送的消息中设置一个标示长度或间隔的字段信息。
由于TCP为应用提供可靠传输,所以需要对数据传输时数据破坏、丢包、重复以及乱序问题有充分的控制能力。同时TCP协议作为面向连接的协议,只有确认对端存在才会发送数据。
TCP通过检验和、序列号、确认应答、重发控制、连接管理、窗口控制等实现可靠传输。
当传输层采用TCP协议进行通信时,TCP数据被封装在一个IP数据报里,首先来看一下TCP首部的构成,不包括可选字段,TCP首部一般是20个字节:
看书的时候把首部各部分的意义画在了图中,简单来说,TCP数据报通过源端端口号和目的端口号来确认彼此使用TCP的程序,序号和确认序号用于完成字节流的标识,使其能够按照发送的顺序被接收。窗口大小指的是滑动窗口协议的大小,检验和用来检验当前收到的数据包是不是有应该收的。具体我都在看书过程中画在图里了。
TCP是面向连接的可靠传输,在每次通信之前都需要先建立链接,建立一个新连接的时候:
- 请求端(客户端)发送一个SYN段指明建立连接的端口,此时TCP首部中,SYN字段被设置为1,序号字段是一个随机生成的初始序号(ISN),可选字段中会有一个己方能够发送的数据包最大长度MSS
- 服务器收到这个报文之后,发送一个ACK给客户端,这个数据包中,ACK和SYN字段被设置为1,序号字段是一个随机生成的初始序号(与客户端的不同),确认序号字段是客户端的ISN+1,可选字段有一个服务器所能够发送的MSS
- 客户端接收到这个报文之后,发送一个ACK给服务器,这个数据包中,ACK字段为1,确认序号为服务器的ISN+1
MSS的确认是建立连接的过程中实现,但是如果有一方不接收来自另一方的MSS,则设定为默认值536(这个默认值允许20字节的IP首部以及20字节的TCP首部以适合576字节的IP数据报)
在通信结束之后,需要经过4次挥手断开链接(这是由TCP的半关闭造成的),在这个过程中,第一个发送FIN的执行主动关闭,另一方执行被动关闭。当客户端结束数据传输,给对方发送一个FIN数据包请求关闭链接,,服务器收到FIN后回复一个ACK。而后服务器再给客户端发送一个FIN请求关闭链接,客户端回复一个ACK,即可完成关闭。
附图:TCP/IP详解(注意建立连接与关闭链接中双方的序号关系,起始ISN是随机产生的)
在建立连接与断开链接的过程中,有一个非常重要的问题,就是丢包处理。一般会设置一个最长等待时间,当发送方超过最长等待时间接收不到对方回复,就会重发刚才的数据包。而接收方如果接到数据包,会根据序号(或其他策略)判断是不是重复的数据包从而接收或者丢弃。
还有很重要的在建立连接与关闭链接过程中,TCP的状态变迁:
- TIME_WAIT状态也称为2MSL等待状态,MSL是任何报文段被丢弃前在网络内存活的最长时间。当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留时间为2倍的MSL,这样可以让TCP再次发送最后的ACK防止ACK丢失。另外,谁执行主动关闭,谁进入TIME_WAIT状态,谁被动关闭,谁进入CLOSE_WAIT状态
- FIN_WAIT_2状态,是已经发出FIN并且另一端已经确认,除非实行半关闭,否则等待另一端发送FIN请求关闭链接。只有当另一端的进程完成这个关闭,这端才会从FIN_WAIT2状态进入TIME_WAIT状态