TCP基础及连接与释放

概述

TCP/IP结构中,最主要的传输层协议就是传输控制协议(TCP, Transmission Control Protocol),它具有如下主要特性:

  1. 面向连接

    在使用TCP前必须建立TCP传输连接,而且使用完后也必须释放连接。

    有很多网络攻击手段就是利用这个特性实现的。

  2. 仅支持单播传播

    每条TCP传输连接只能点对点传输,不支持多播及广播的方式传输。

  3. 可靠的服务

    TCP连接提供的传输服务是无差错不丢失不重复按序的

  4. 数据段为传输单位

    TCP仍然采用传统的数据段作为数据单元,但数据段大小受应用层传送的报文大小和途径网络中的MTU值大小决定,所以每次发送TCP的数据段大小是不固定的。有一个最大数据段大小(MSS, Maximum Segment Size)来指示最大大小。

  5. TPDU格式只有一种

    TCP的数据单元称为数据段,但也可以按OSI/RM中称为TPDU。在TCP中只有一种TPDU格式。

  6. 支持全双工

    TCP允许通行双方在任何时候都能发送数据,因为这种连接方式在两端都有缓冲区用于临时存放数据。它也支持立即发送一个数据,也可以缓存一段时间一次性发送更多的数据(最大大小取决于MSS的值)。

  7. 连接基于字节流

    TCP的传输并不像UDP一样是按报文为单位的,而是没有边界的,均以字节流的方式传输

  8. 每次发送的数据段大小和数量都是不固定的

    每次可以发送多少字节是不固定的,也不由可用缓存决定,而是根据对方给出的窗口网络的拥塞程度决定的。

    另外,在缓存中的数据过多,会对它进行分段。反之,如果缓存中数据过小,则会等待到有一定量的数据再组装一起发送。


TCP数据段格式

数据段(Segment)这个叫法来自协议数据单元的。TCP软件决定了数据段的大小,因为既可以将多次写操作汇聚到一起,也可以将一个写入操作分割。

但是仍然有两个因素决定了数据段的大小:一是TCP数据段的大小必须在IP数据报的有效载荷范围内,二是最终仍然需要符合MTU限制。

TCP通过数据段的交互来执行连接、传输、确认、差错控制、流量控制及关闭等操作。整个数据段也分为段头数据两部分,所以也可以将其看做报文。

和其他报头类似的,段头是为了实现可靠传输加上的控制信息,而数据部分则是高层发来的用户数据。

下图是它的段头格式:

TCP Segment Header

  1. 源端口/目的端口(Source Port/Destination Port)

    表示发送方和接收方的TCP端口号,各占16位(2字节)。一个端口与主机IP地址就可以组成套接字(Socket)。

  2. 序号(Seq, Sequence Number)

    表示数据部分第一个字节的编号,占32位(4字节)。在TCP连接中,所有传送的数据都要以字节为单位编号,其起始序号必须在连接建立时设置。

  3. 确认号(Ack, Acknowledgement Number)

    表示期望收到下一个数据段的数据部分起始序号,占32位(4字节)。注意,确认号表示的是期望的下一个,不是已经正确接受的最后一个,这点上有点语义上的混淆,需注意。

    序号和确认号共同支撑TCP中的差错控制服务。

  4. 数据偏移(Parity)

    表示数据部分距离数据段头起始处的偏移量以4字节为单位,占4位(1字节)。该字段用于确认数据段头的长度,因为TCP和IP数据报一样具有可选项,所以需要该字段来确认实际长度。

    根据该字段的长度可以得知,数据偏移量最大为60字节,所以TCP段头最大长度也只有60字节。

  5. 保留(Reserved)

    目前无作用,占6位。因为无作用所以设置为全0。

  6. 六位控制标志

    1. 紧急指针位(URG, Urgent Pointer)

      该位为1代表有紧急数据,且仅当本位为1时后面的紧急指针字段才有意义。

    2. 确认位(ACK, Acknowledgement)

      指示该数据段中确认号字段有效,否则应用层读取数据时会无视确认号字段。

    3. 推送位(PSH, Push)

      指示是否立即把接收到的数据交付给应用进程,如果否,则可能会被缓存到足够数量再一次性交付。

    4. 重置位(RST, Reset)

      指示需要重新建立当前连接,当连接出现问题期望重新建立连接时使用。

    5. 同步位(SYN, Synchronization)

      指示该段是一个连接请求或连接确认报文当置为1且ACK置为0时,表示请求连接,当两者都置为1时,表示确认连接

    6. 结束位(FIN, Final)

      指示要求释放连接,当发送端已经传输完毕或不再需要连接时置为1。注意,如果接收端此时仍未接受完毕数据可以继续接受。

  7. 窗口大小(Window)

    指示发送方的窗口大小,也就是发送者当前还可以接收的最大字节数,占16位(2字节)。

  8. 校验和(Checksum)

    对数据段头、数据、伪头部三部分进行的校验和校验码,占16位(2字节)。

    伪头部包含源主机/目的主机IP地址、TCP协议号、TCP数据段长度。

  9. 紧急指针(URG, Urgent Pointer)

    当紧急指针位为1时,该指针用于指明紧急数据在数据段中的位置,占16位(2字节)。

    要注意的是,即使窗口大小为0,紧急数据仍然可以发送,因为紧急数据是不被缓存的。

  10. 可选(Option)

    该字段最长可达40字节,它可以有任意数据,但一般有窗口缩放选项(WSopt, Window Scale Option)最大数据段大小(MSS, Maximum Segment Size)时间戳(Timestamp)等。

  11. 数据(Data)

    由应用层提交的数据。


TCP连接状态转移

TCP的Socket服务原语(Primitive)只有8个,比OSI/RM结构中定义的更少,但是这些原语中可以有不同的状态。如下表所示:

状态描述
CLOSED阻塞、关闭状态,表示主机没有活动连接
LISTEN监听状态,表示主机正在等待新的连接进入
SYN RCVD主机已收到连接请求,但未确认
SYN SENT主机已经发送一个连接请求,等待对方确认
ESTABLISHED连接建立,双方进入正常数据传输状态
FIN WAIT 1(主动关闭)主机已发送关闭连接请求,等待对方确认
FIN WAIT 2(主动关闭)主机已收到对方关闭连接确认,等待对方发送关闭连接请求
TIMED WAIT完成双向传输连接关闭,等待所有分组消失
CLOSING双方同时尝试关闭连接,等待对方确认
CLOSE WAIT(被动关闭)收到对方关闭连接请求,并且已确认
LAST ACK(被动关闭)等待最后一个关闭连接确认,并等待所有分组消失

这种建立和释放过程中的状态又称为有限状态机(FSM, Finite State Machine)

下图详细描述了通信主机在各种过程中的状态机,其中方框表示主机不同时期的状态、箭头表示状态之间的转换、注释表示状态转换进行的操作。

而粗线是客户端主动连接服务端的正常过程,其中客户端状态转移用带箭头的粗实线表示,服务端的状态转移用带箭头的粗虚线表示。

带箭头的细线表示一些不常见的事件,如复位、同时打开、同时关闭等。

TCP FSM


TCP连接的建立

TCP是使用三次握手机制来建立连接的,其流程见下图:

TCP Connect

简单的剖析一下这个过程:

  1. 首先服务器要经过初始化过程,从CLOSED状态顺序调用SOCKET、BIND、LISTEN、ACCEPT原语来创建Socket并进入LISTEN状态,等待客户端连接请求。

  2. 客户端也从CLOSED状态开始调用SOCKET等原语创建Socket,然后调用CONNECT原语来请求建立连接。它会主动打开端口,向服务器发送一个SYN标志为1(表示这是一个同步数据段)且有c为序列号的数据段到服务器,随后便进入了SYN SENT状态

  3. 服务器收到该SYN数据段后会被动的打开端口,并且返回一个SYN及ACK标志为1(表示这是一个同步确认数据段)且确认号为c+1并有s为序列号的数据段,随后进入SYN RCVD状态

    这个过程一定要注意确认号是期望收到的下一个序列号,因此是c+1而不是c。

  4. 客户端收到来自来自服务器的SYN+ACK数据段后,向服务器发送一个ACK标志为1且确认号为s+1并有c+1为序列号的数据段,随后进入ESTABLISHED状态(此时已经建立单向连接)。

    要注意的是,只有单独ACK标志的数据段,并不实际使用序号,当客户端实际发送数据时,第一个序号仍然为c+1。

  5. 服务器收到来自客户端的ACK数据段后,也进入ESTABLISHED状态,这时便完成了双向连接状态

三次握手的基本流程如上所述,可以看见,序号和确认号是通信过程中非常重要的,另外,这个三次握手的流程可以协商双方的情况,如MSS的值等。

双方同时建立连接

有时候可能会出现双方同时向对方建立连接的情况,但这种情况也不会产生影响,只是状态有些变化,但最终建立的仍然是一个连接,其流程见下图:

TCP BothConnect


TCP连接的释放

当TCP建立连接后,数据可以在两个方向互不干扰的传送,当应用进程再没有数据需要发送时,就可以发送关闭连接请求。但是发送请求后,关闭的是发往对方的数据流通道,本端仍然可以接收来自对方的数据。除非对方也同样的发出了关闭连接请求,这样双方的连接就会彻底关闭。

由于TCP有半关闭状态(因双端都需要各自关闭,这也是全双工的特性),所以TCP的释放是四次握手流程。它的具体流程如下图所示:

TCP Final

  1. 一开始,通信双方都处于ESTABLISHED状态,假定客户端认为数据已经发送完了,准备结束本次连接,则由应用进程调用CLOSE原语,向服务器发送一个FIN标志为1并有c为序列号的数据段,随后进入FIN WAIT 1状态

  2. 服务器收到FIN数据段后,在确认没有数据待接收(如需要重传的部分,未接收完成的部分),会向客户端发送一个ACK标志为1且确认号为c+1的数据段,随后进入CLOSE WAIT状态,与此同时通知服务器上对应的应用程序,释放从客户端到服务器方向的连接,进入半关闭状态

    注意,此时服务器仍然可以向客户端发送数据。

    另外,该ACK数据段同时也向客户端表示前面的数据已经全部正确接收。

  3. 当客户端收到ACK数据段后,进入FIN WAIT 2状态。继续等待服务器发送释放连接的数据段。

  4. 当服务器也没有数据要发送后,其应用进程会通知TCP**释放从服务器到客户端方向的连接,此时会向客户端发送**FIN及ACK标志为1且确认号为c+1并有s为序列号的确认数据段,随后进入LAST ACK状态,等待客户端的确认。

  5. 当客户端收到FIN+ACK数据段后,向服务器发送一个ACK标志为1且确认号为s+1并有c+1为序列号的数据段,随后进入TIME WAIT状态

    此时连接并没有关闭,必须等待2MSL时间才会彻底关闭进入CLOSED状态。

    RFC793建议MSL为2分钟。

  6. 服务器收到来自客户端的ACK数据段后,进入CLOSED状态,彻底释放连接。

双方同时释放连接

关闭时,也有可能出现双方同时释放的情况,但并不常见,其流程如下图所示:

TCP BothFinal

文中图片来自《深入理解计算机网络》

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值