重学TCP之TCP的基本认识

Posted 刘小豆豆豆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重学TCP之TCP的基本认识相关的知识,希望对你有一定的参考价值。

TCP的基本认识

什么是 TCP ?

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

  • 面向连接 :一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;
  • 可靠的 :无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端;
  • 字节流 :消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。

TCP的头格式

序列号 :在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。

确认应答号 :指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。

控制位:

  • ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。
  • RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
  • SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
  • FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。

TCP如何保证可靠性

  • 数据分块

    应用数据被分割成 TCP 认为最适合发送的数据块。

  • 序列号和确认应答

    TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。

  • 校验和

    TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。

  • 流量控制:

    通过滑动窗口来实现,TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制,主要是根据接收端的接收情况,动态去调整Window Size,然后来控制发送端的数据流量)

  • 拥塞控制:

    慢启动和拥塞避免,快重传,快恢复。

  • ARQ协议

    也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。

  • 超时重传:重传定时器, 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

UDP与TCP的区别

UDP 不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务。

UDP 协议真的非常简,头部只有 8 个字节( 64 位),UDP 的头部格式如下:

  • 目标和源端口:主要是告诉 UDP 协议应该把报文发给哪个进程。
  • 包长度:该字段保存了 UDP 首部的长度跟数据的长度之和。
  • 校验和:校验和是为了提供可靠的 UDP 首部和数据而设计。

TCP 和 UDP 区别:

  1. 连接
    • TCP 是面向连接的传输层协议,传输数据前先要建立连接。
    • UDP 是不需要连接,即刻传输数据。
  2. 服务对象
    • TCP 是一对一的两点服务,即一条连接只有两个端点。
    • UDP 支持一对一、一对多、多对多的交互通信
  3. 可靠性
    • TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达。
    • UDP 是尽最大努力交付,不保证可靠交付数据。
  4. 拥塞控制、流量控制
    • TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。
    • UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。
  5. 首部开销
    • TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的。
    • UDP 首部只有 8 个字节,并且是固定不变的,开销较小。
  6. 传输方式
    • TCP 是流式传输,没有边界,但保证顺序和可靠。
    • UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。
  7. 分片不同
    • TCP 的数据大小如果大于 MSS(最大报文段长度) 大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
    • UDP 的数据大小如果大于 MTU(最大传输单元) 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层,但是如果中途丢了一个分片,则就需要重传所有的数据包,这样传输效率非常差,所以通常 UDP 的报文应该小于 MTU。

由于 TCP 是面向连接,能保证数据的可靠性交付,因此经常用于:

  • FTP 文件传输
  • HTTP / HTTPS

由于 UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:

  • 包总量较少的通信,如 DNS 、SNMP 等
  • 视频、音频等多媒体通信
  • 广播通信

UDP 为什么是不可靠的?bind 和 connect 对于 UDP 的作用是什么

UDP 只有一个 socket 接收缓冲区,没有 socket 发送缓冲区,即只要有数据就发,不管对方是否可以正确接收。而在对方的 socket 接收缓冲区满了之后,新来的数据报无法进入到 socket 接受缓冲区,此数据报就会被丢弃,因此 UDP 不能保证数据能够到达目的地,此外,UDP 也没有流量控制和重传机制,故UDP的数据传输是不可靠的。

connect由内核指定端口号,bind由函数指定端口号。

TCP停止等待协议(ARQ)

自动重传请求(Automatic Repeat-reQuest,ARQ)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。

ARQ包括停止等待ARQ协议和连续ARQ协议。

  • 停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;
  • 在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认;

TCP最大连接数限制

客户端:65535

服务器端:客户端数*客户端port数 即 2的32次方×2的16次方 = 2的四十八次方

TCP流量控制和拥塞控制

流量控制:滑动窗口机制,主要的方式是接收方返回的 ACK 中会包含自己的接收窗口大小,以控制发送方此次发送的数据量大小(发送窗口大小)。

拥塞控制:满开始和拥塞避免、快重传和快恢复。

如果接收方滑动窗口满了,发送方会怎么做

启动坚持计时器辅助发送方周期性地查询接收方接收窗口大小。

拥塞控制采用的四种算法

慢开始:初始拥塞窗口为1,之后每接收到一个确认报文,拥塞窗口增大,直到增加到慢开始阈值ssthresh。

拥塞避免:说白了就是加法增大。

快重传:假定发送方发送了 Msg 1 ~ Msg 4 这 4 个报文,已知接收方收到了 Msg 1,Msg 3 和 Msg 4 报文,此时因为接收到收到了失序的数据包,按照快重传的约定,接收方应立即向发送方发送 Msg 1 的重复确认。

快恢复:① 当发送方连续收到三个重复确认,执行乘法减小,慢开始门限 ssthresh 值减半;

② 由于发送方可能认为网络现在没有拥塞,因此与慢开始不同,把 cwnd 值设置为 ssthresh 减半之后的值,然后执行拥塞避免算法,线性增大 cwnd。

TCP粘包问题

为什么会发生:

  • 要写入的数据大于套接字缓冲区的大小,要把数据分开发送。
  • 要写入的数据小于套接字缓冲区的大小,会使用Nagle算法,在接收到一个ACK确认后,才将组合的字节流一起发给对面,这会发生粘包。
  • TCP报文段会分段。
  • 发送方发送数据太快,接收方处理速度慢,在buffer里发生粘包。

以上是关于重学TCP之TCP的基本认识的主要内容,如果未能解决你的问题,请参考以下文章

TCP 之 TCP首部

TCP之报文首部格式

TCP连接之报文首部

TCP/IP之TCP协议首部三次握手四次挥手FSM

计算机网络—— 运输层:TCP报文段的首部格式

002::每天五分钟入门TCP/IP协议栈::IP协议之IP首部长度问题