主要特点

TCP是面向连接(虚连接)的运输层协议;
每一条TCP连接只有两个端点,每一条TCP连接只能是点对点的;
TCP提供可靠交付的服务,无差错、不丢失、不重复、按序到达。
TCP提供全双工通信
发送缓存:准备发送的数据&已发送但尚未收到确认的数据
接收缓存:按序到达但尚未被接受应用程序读取的数据&不按序到达的数据
TCP面向字节流:TCP把应用程序交下来的数据看成仅仅是一连串的无结构的字节流。

TCP面向字节流的概念
TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。
image.png
注:TCP 连接是一条虚连接而不是一条真正的物理连接。
TCP 对应用进程一次把多长的报文发送到 TCP 的缓存中是不关心的。
TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。
TCP 可把太长的数据块划分短一些再传送。
TCP 也可等待积累有足够多的字节后再构成报文段发送出去。

TCP的连接

TCP把连接作为最基本的抽象。每一条TCP连接有两个端点,连接的端点叫做套接字或插口,端口号拼接到IP地址即构成了套接字。(socket=IP地址:端口号)
每一条 TCP 连接唯一地被通信两端的两个端点(即两个套接字)所确定。即:
image.png
注:同一个 IP 地址可以有多个不同的 TCP 连接。同一个端口号也可以出现在多个不同的 TCP 连接中。

每个TCP连接都有三个阶段:连接建立、数据传送和连接释放

在TCP连接建立的过程中,要解决以下三个问题:

  • 1)要使每一方都能够确知对方的存在。
  • 2)要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项、时间戳选项及服务质量等)。
  • 3)能够对运输实体资源( 如缓存大小、连接表中的项目等)进行分配。

连接的建立 - - - 三次握手

  • seq为序号字段,标明本次报文段数据部分的第一个字节的序号
  • ack是确认号字段,告诉对方我接下来应该接收的数据是从字节序号ack开始的数据
  • ACK是确认位,0时确认号字段ack无效,1时确认号字段ack有效
  • SYN是同步位

image.png
第一步:客户机的TCP首先向服务器的TCP发送一个连接请求报文段。这个特殊的报文段中不含应用层数据,其首部中的SYN标志位被置为1。另外,客户机会随机选择一个起始序号 seq= x(连接请求报文不携带数据,但要消耗一个序号)。
第二步:服务器的TCP收到连接请求报文段后,如同意建立连接,就向客户机发回确认,并为该TCP连接分配TCP缓存和变量。在确认报文段中,SYN和ACK位都被置为1,确认号字段的值为x+ 1, 并且服务器随机产生起始序号seq = y(确认报文不携带数据,但也要消耗-一个序号)。确认报文段同样不包含应用层数据。
第三步:当客户机收到确认报文段后,还要向服务器给出确认,并且也要给该连接分配缓存和变量。这个报文段的ACK标志位被置1,序号字段为x+1,确认号字段ack=y+ 1。该报文段可以携带数据,若不携带数据则不消耗序号。
成功进行以上三步后,就建立了TCP连接,接下来就可以传送应用层数据。

TCP连接释放——四次握手

image.png
第一步:客户机打算关闭连接时,向其TCP发送一个连接释放报文段, 并停止发送数据,主动关闭TCP连接,该报文段的FIN标志位被置1, seq=u, 它等于前面已传送过的数据的最后一个字节的序号加1 (FIN报文段即使不携带数据,也要消耗一个序号)。
TCP 是全双工的,即可以想象为一条TCP连接上有两条数据通路。
发送FIN报文时,发送FIN的一端不能再发送数据,即关闭了其中一条数据通路,但对方还可以发送数据。
第二步:服务器收到连接释放报文段后即发出确认,确认号是ack=u+ 1,而这个报文段自己的序号是v,等于它前面已传送过的数据的最后一个字节的序号加1。
此时,从客户机到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。
但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭。
第三步:若服务器已经没有要向客户机发送的数据,就通知TCP释放连接,此时其发出FIN= 1的连接释放报文段。
第四步:客户机收到连接释放报文段后,必须发出确认。在确认报文段中,ACK字段被置为1,确认号ack=w+1,序号seq=u+1.此时TCP连接还未释放,必须经过时间等待计时器设置的时间2MSL后,A才进入连接关闭状态。

TCP报文段的首部格式

TCP传送的数据单元称为报文段。一个TCP报文段分为TCP首部和TCP数据两部分,整个TCP报文段作为IP数据报的数据部分封装在IP数据报中
其首部的前20B是固定的。TCP报文段的首部最短为20B,后面有4N字节是根据需要而增加的选项,通常长度为4B的整数倍。
TCP报文段既可以用来运载数据,又可以用来建立连接、释放连接和应答。
image.png
源端口和目的端口字段:各占2个字节。端口是运输层与应用层的服务接口。运输层的复用与分用功能都要经过端口才能实现;
序号字段:占 4 字节。TCP 连接中传送的数据流中的每一个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号;
确认号字段:占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号;
数据偏移(即首部长度):占 4 位,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。“数据偏移”的单位是 32 位字(以 4 字节为计算单位);
保留字段——占 6 位,保留为今后使用,但目前应置为 0;
紧急 URG —— 当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据);
确认 ACK —— 只有当 ACK =1 时确认号字段才有效。当 ACK =0 时,确认号无效;
推送 PSH (PuSH) —— 接收 TCP 收到 PSH = 1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付;
复位 RST (ReSeT) —— 当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接;
同步 SYN —— 同步 SYN = 1 表示这是一个连接请求或连接接受报文;
终止 FIN (FINish) —— 用来释放一个连接。FIN=1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接;
窗口字段 —— 占 2 字节,用来让对方设置发送窗口的依据,单位为字节;
检验和 —— 占 2 字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部;
紧急指针字段 —— 占 16 位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面);
选项字段 —— 长度可变。TCP 最初只规定了一种选项,即最大报文段长度 MSS。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”;(MSS是“TCP 报文段长度减去 TCP 首部长度”。)
填充字段。这是为了使整个首部长度是4B的整数倍。填充0.

以下方面了解即可
TCP拥塞控制(慢开始与拥塞避免、快重传和快恢复)
https://bithachi.blog.csdn.net/article/details/105532044
TCP流量控制
https://bithachi.blog.csdn.net/article/details/105531547
TCP可靠传输
https://bithachi.blog.csdn.net/article/details/105524592