[计算机网络]-TCP-概述

TCP概述

RFC文档地址
TCP 协议是 TCP/IP 协议簇中位于运输层的协议

TCP/IP四层体系结构

可以看到运输层的两个主要协议除了 TCP ( T r a n s m i s s i o n   C o n t r o l   P r o t o c o l Transmission\ Control\ Protocol Transmission Control Protocol,传输控制协议) 还有一个 UDP ( U s e r D a t a g r a m P r o t o c o l User Datagram Protocol UserDatagramProtocol,用户数据报协议)

TCP 和 UDP 有什么区别

  1. 连接:TCP 提供 面向连接的可靠的 数据传输服务;而 UDP 提供的是 无连接的尽最大努力的 数据传输服务,不保证传输的可靠性
  2. 服务对象:TCP 是一对一的两点服务,即一条连接只有两个端点;UDP 支持 一对一,一对多,多对多 的交互通信
  3. 可靠性:TCP 是 可靠交付数据 的,数据可以无差错,不丢失,不重复,按需到达;UDP 是尽最大努力交付,不保证可靠地交付数据
  4. 拥塞控制:TCP 具有 拥塞控制流量控制 的机制,保证了数据传输的安全性跟可靠性;UDP 则没有相关的机制,即使网络非常拥塞也不影响其发送速率
  5. 首部开销:TCP 首部长度较长,在没有使用 “选项” 字段时就已经需要 20 个字节;UDP 首部只有 8 个字节,并且是固定不变的
  6. 传输方式:TCP 是面向字节流的,是流式传输,没有边界,但保证数据传输的顺序和可靠,其数据传输单位是 报文段;UDP 是一个包一个包地发送,是有边界的,但可能会丢包和乱序,传输单位为 用户数据报

各自的应用场景:

  • TCP:由于 TCP 是面向连接的,能保证数据的可靠性交付,经常用于:用于万维网的 HTTP,HTTPS;用于文件传送的 FTP;用于电子邮件传送的 SMTP(简单邮件传送协议);用于远程终端接入的 TELNET(远程终端协议)
  • UDP:UDP 不需要连接,可以随时发送数据,而且没有拥塞控制,不保证可靠性,所以经常用于:包总量较少的通信,如域名转换 DNS,网络管理 SNMP(简单网络管理协议);但由于实时性强,适用于实时应用,如 IP 电话,实时视频会议等场景,这种场景对于实时要求很大,而且缺失了那么几个帧对整体数据的影响又不是很大

可以看出衡量的点可以考虑所传数据的多少,对实时性要求的大小,对数据可靠性要求的大小
有的应用场景也并不是说只会使用两种其中一种协议,如 DNS,一般使用 UDP 就足够,但也可能会出现需要访问较远距离的域名服务器的情况,此时就可能需要使用TCP了

TCP 的服务模型

TCP 提供了一种 面向连接的可靠字节流 服务
面向连接,即使用 TCP 的两个应用程序必须在双方交换数据之前必须建立一个 TCP 连接

在字节流抽象概念中:

  1. 没有由 TCP 自动插入的 记录标志 或 消息边界。连接的双方对数据进行读写时,读或写的次数以及每次读或写的大小由端点自己选择
  2. TCP 不会解读字节流里的字节内容,他不知道正在交换的数据字节是不是二进制数据,ASCII 字符或其他东西。对字节流的解读只取决于连接的端点的应用程序

TCP 的可靠性

TCP 通过 校验和,序列号,确认应答,连接管理,超时重传,滑动窗口机制,流量控制拥塞控制 等机制实现可靠性传输

  • 因为 TCP 提供的是字节流接口,它必须把一个发送端应用程序的字节流转换成 IP 可以携带的分组,这被称为 组包,这些分组都包含 序列号,该序列号代表的是 每个分组的第一个字节在整个数据流的字节偏移,这就允许了分组在传送中是可变大小的,并允许 重新组包。由 TCP 传给 IP 的数据块称为 报文段( s e g m e n t segment segment)
  • 如果一个携带无效 校验和 的报文段到达,那么 TCP 会丢弃它,不为被丢弃的分组发送任何确认
  • TCP 发送一组报文段时,会设置 重传计时器,然后等待对方发送成功接收报文段的确认 ACK,如果有 ACK 没有及时接收到,对应的报文段就会被 重传。当 TCP 接收到连接的另一端的数据时,就会发送一个 ACK。不过 TCP 使用的是 累积确认,即 一个指示字节号 N 的ACK,暗示着所有直到序号 N (不包括 N) 的字节都已经成功被接收了,这对于 ACK 丢失来说带来了一定的 鲁棒性,如果一个 ACK 丢失,很有可能后续的 ACK 就足以确认前面的报文段了,避免了前面的 ACK 丢失所带来的影响
  • TCP 提供的是 全双工通信,数据可向两个方向流动,两个方向相互独立。每个方向上的报文段发送各自的 ACK,同时包含 窗口通告 以实现相反方向上的 流量控制
  • 使用 序列号一个 TCP 接收端可丢弃重复的报文段和记录以杂乱次序到达的报文段。因为 TCP 使用 IP 来传递其报文段,而 IP 不提供重复数据消除以及保证次序正确的功能。而 TCP 是一个字节流协议,绝不会以杂乱的次序给接收端应用程序发送数据,因此接收端会被迫先保存大序列号的数据不交给应用程序,直到中间缺失的部分那些小序列号的报文段接收到了,填补了整个字节流的空缺,再继续发送字节流数据

TCP的头部和封装

TCP 在 IP 数据报中的封装如图:
TCP在IP数据报中的封装

TCP 头部如图:
TCP头部

  1. 每个 TCP 头部中都包含了 源端口目的端口,这两个值和 IP 头部中的 源IP地址 以及 目的IP地址这样的四元组唯一地表示了每个连接。一个 IP 地址和一个端口的组合有时又称为一个 端点( e n d p o i n t endpoint endpoint) 或 套接字( s o c k e t socket socket)

  2. 序列号 是一个 32 位的无符号数,每一个报文段对应一个序列号,它代表的就是该报文段的数据中第一个字节的序列号,因为 TCP 会给两个应用程序间通信的数据流中的每个字节都赋予一个序列号 (这里考虑的数据流只考虑一个方向上的,一个连接的两个方向相互独立)。序列号到达 232 - 1 后再循环回到 0

  3. 确认号 ACK 包含的值是 该确认号的发送方期待接收的下一个序列号,也即 最后一个被成功接受的数据字节的序列号加 1,也可以这么理解,对于发送这个 ACK 的通信方来说,这个序列号以前 (不包括这个序列号) 的所有序列号它都已经接收到了

    这个字段只有在 ACK 位字段被启用的时候有效,而这个 ACK 位字段通常在一个连接中,除了初始报文段跟末尾报文段之外。其它报文段中都会启用

    由于 ACK 就是报文段头部的一部分,所以发送一个 ACK 跟发送任何报文的开销是一样的

  4. 头部长度 字段给出了头部的长度。因为头部中除了 基本部分 固定是 20 字节以外,选择字段的长度是可变的,所以为了知道整个头部的长度,这个头部长度字段是必需的

    头部长度字段共占 4 位,它的值以 32 位为单位,也就是说,0000 表示头部长度为 0 位,0001 表示头部长度为 32 位,0010 表示头部长度为 64 位…所以最大值 1111 表示长度为 60 字节,即 TCP 头部最长只能为 60 字节。而基本的 TCP 头部长 20 字节,也就是说选项字段最长为 40 字节。也是因为头部长度字段以 32 位为单位,所以 TCP 头部的长度应该是 32bit 的倍数

  5. 保留 字段保留为今后使用,目前全置 0

  6. 头部中定义了8位 控制位
    – CWR:拥塞窗口减 (表示发送方已降低其发送速率,见 TCP 拥塞控制部分)
    – ECE:ECN 回显 (表示发送方接收到了一个更早的拥塞通告,见 TCP 拥塞控制部分)
    – URG:紧急 (紧急指针字段有效,很少被使用)
    – ACK:确认 (确认号字段有效,建立连接之后一般都是启用状态)
    – PSH:推送 (接收方应尽快给应用程序传送这个数据,不过这个功能没被可靠地实现或用到)
    – RST:重置连接 (连接取消,经常是因为错误)
    – SYN:用于初始化一个连接的同步序列号
    – FIN:该报文段的发送方已经结束向对方发送数据

  7. TCP 的流量控制由每个端点使用 窗口大小 字段来通告一个窗口大小来完成。这个窗口大小是字节数,从接收方想要接收的那个字节开始算起。由于字段所占长度只有 16 位,所以 窗口大小最大只能为 65535 字节,从而限制了 TCP 的吞吐量性能

    不过有一个 窗口缩放 选项可允许对这个值进行缩放,从而给高速和大延迟网络提供了更大的窗口和改造性能

  8. 校验和 字段由发送方进行计算和保存,然后由接收方验证

  9. 紧急指针 字段只有 URG 位启用时才有效。其值是一个正偏移量,与报文段的序列号字段相加后得到的值就是 紧急数据的最后一个字节的序列号

  10. 选项 字段:
    >>> 最常见的选项是最大段大小 MSS ( M a x i m u m   S e g m e n t   S i z e Maximum\ Segment\ Size Maximum Segment Size)。连接的每个端点一般在它发送的第一个报文段,即 SYN 报文段 上指定这个选项,MSS 指定该选项的发送者在相反方向上希望接收到的报文段的最大值
    >>> 除此之外还有 SACK,时间戳 和 窗口缩放 等选项

字节序

参考文章
字节序讨论的问题是,在存储一个 由多于一个字节所组成的数据 时,是将其高位的字节放在低地址,低位的字节放在高地址,还是将其高位的字节放在高地址,低位的字节放在低地址

具体可分为大端 (Big Endian) 字节序和小端 (Little Endian) 字节序,大端指的就是 高位字节放在低地址,低位字节放在高地址;小端则与之相反

单台计算机自己本身想选择大端或者小端可以自己自由选择,这称为 主机字节序

而网络的出现使得多台计算机之间需要通信,这时候就要规定好一个通信所用的字节序保证通信内容解析正确。在 TCP 中,RFC 1700 规定使用 “大端” 字节序作为 网络字节序,其他不使用大端字节序的计算机在发送数据时必须将自己的主机字节序转换为网络字节序 (即 “大端” 字节序);接收到的数据再转换为自己的主机字节序。这样字节序就与 CPU、操作系统 无关了,实现了网络通信的标准化

猜你喜欢

转载自blog.csdn.net/Pacifica_/article/details/123929280