0%

读书笔记-TCP/IP详解 卷1:协议

不同层的PDU(Protocol Data Unit)

  • 传输层:Segment(帧)
  • 网络层: Packet
  • 链路层:Frame
  • 物理层: Bit

链路层

  • MTU 到底是怎么来的

MTU, 是 Maximum Transmission Unit 的缩写, 根据 Wikipedia 的定义, MTU 指的是在 Network Layer (因处 OSI 第三层, 后以 L3 代替)上传输的最大数据报单元, 而 MTU 的大小一般由 Link Layer (因处 OSI 第二层, 后以 L2 代替) 设备决定. 比如生活中使用最广泛的以太网(Ethernet, IEEE 802.3)的帧大小是 1518 字节, 根据 Ethernet Frame 的定义, L2 Frame 由 14 字节 Header 和 4 字节 Trailer 组成, 所以 L3 层(也就是 IP 层)最多只能填充 1500 字节大小, 这就是 MTU 的由来.

MTU:46~1500

物理层扩展以太网:集线器
链路层扩展以太网:网桥、交换机

隧道:在高层(或同等层)分组中携带底层数据

Internet协议

IPv4 - Packet Structure

DHCP

防火墙、NAT

ICMP

UDP

UDP校验和覆盖了UDP头部、UDP数据和一个伪头部。
它不提供差错纠正、队列管理、流量控制和拥塞控制。

面向数据报:应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会是IP太小。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。

TCP: 传输控制协议(初步)

  • 差错纠正:接收方收报,校验和字段,校验失败时,不回ACK;发送端会重新发送。
  • 流量控制(flow control):接收方相对发送方太慢时,会窗口更新(window update),告诉发送方,调整其窗口大小,从而降低发送包的速度
  • 拥塞控制(congestion control):中间的网络(比如路由器)丢包,减缓TCP发送
  • 面向字节流: 虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流。TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。
  • 分组窗口(window)

  • 窗口大小(windows size)

  • 滑动窗口(sliding window)协议

  • 组包(packetization):把一个发送应用程序的字节流转换成一组IP可以携带的分组。分组的序列号表示了每个分组的第一个字节再整个数据流中的字节偏移,而不是分组号。在传输过程中允许重新组包(repacketization)

  • 校验和:TCP维持了一个较强的校验和,该校验和涉及它的头部、任何相关应用程序数据和IP头部的所有字段。是一个端到端的伪头部,用于检测传送中引入的比特差错。

  • 当TCP收到连接另一端的数据时,会发送一个确认。这个确认可能不会立即发送,一般会延迟片刻。TCP使用的ACK是累积的,从某种意义来讲,一个指示字节好N的ACK暗示着所有直到N的字节(但不包含N)已经成功接收了。

  • 双工服务

  • 使用序列号,TCP丢弃重复报文和记录以杂乱次序到达的报文段,将正确次序的数据交给应用程序。因此,TCP接收端可能会被迫先保持大序列号的数据不交给应用程序,直到确实的小序列号到达报文段(一个“洞“)被填满。

TCP头部和封装

  • TCP MSS

MSS (Maximum Segment Size)是 TCP Layer (L4) 的属性, MSS 指的是 TCP payload的长度. 当在MTU 1500 的网络上传输时, MSS 为 1460 (即 1500 减去 20 字节 IP 头, 20 字节 TCP 头).

TCP连接管理

  • 普通TCP连接的建立与终止

  • TCP半关闭

TCP的半关闭操作是指仅关闭数据流的⼀一个传输⽅方向, ⽽而两个半关闭操作合在⼀一起就能够关闭整个连接。
例如, 应⽤用程序表明“ 我 已经完成了了数据的发送⼯工作, 并发送⼀一个F I N 给对⽅方, 但是我仍然希望接收来⾃自对⽅方的数据 直到它发送⼀一个F I N 给我” 。伯克利利套接字的A P I 提供了了半关闭操作。应⽤用程序只需要调⽤用shutdown函数来代替基本的close函数, 就能实现上述操作。然⽽而, 绝⼤大部分应⽤用程序仍然会调⽤用close函数来同时关闭⼀一条连接的两个传输⽅方向。

图中左侧的客户端发起了半关闭

  • 初始序列号(英文为:Initial Sequence Number,简称ISN) 按理来说,B应该把这个数据报丢弃掉才是。但是由于A每次发送报文都使用了相同的序号(SEQ = 1),这可能会让B误认为这200字节是属于新建立的tcp连接的,因此B会对这200字节数据照收不误。这就导致B在收到新tcp连接的数据后,又收到旧tcp连接的数据,从而出现数据乱序的问题。

这其实反映了tcp的一些缺点,如果被一些恶意攻击者加以利用tcp的这种缺点:选择合适的序号,ip地址和端口的话,就能伪造出一个tcp报文段,从而打断正常的tcp连接。但是初始化序号的方式(通过算法来随机生成序号)就会使序号难以猜出,也就不容易利用这种缺点来进行一些恶意攻击行为。

一般来说,这个序号的范围是0 ~ 2^31 - 1之间,而且序号的生成也是随机的,

  • TCP选项

MSS: 最⼤段⼤小是指TCP协议所允许的从对⽅方接收到的最⼤大报⽂文段。只记录TCP的payload的字节数。典型值1460

  • TIME_WAIT状态
    等待通信另一方重传它的FIN

  • 重置报文段

当发现一个到达的报文段对于相关连接而言是不正确的,TCP就会发送一个重置报文段。TCP头部的RST位字段。重置报文段通常会导致TCP连接的快速拆卸。

1)针对不存在端口的请求连接
2)终止一条连接(终止释放): 
任何排队的数据都将被抛弃,一个重置报文段会被立即发送出去;重置报文段的接收方会说明通信另一端采用了终止的方式而不是正常关闭。
3)半开连接
如果再未告知另一端的情况下通信的一端关闭或终止连接,那么就认为该TCP连接处于半开状态。
发生在一方的主机崩溃的情况下。只要不同过半开连接传数据,正常工作的一端不会检测出另一端已经崩溃。

更多的rst情况参考tcp rst产生的几种情况

TCP超时与重传

RTO: Retransmission Timeout 重传超时

RTT: Round Trip Time

TCP数据流与窗口管理

  • 交互式通信

  • 延时确认(Delayed Acknowledgement)

  • Nagle算法

Nagle算法要求, 当⼀个TCP连接中有在传数据(即那些已发送但还未经确认的数据),小的报文段(长度小于SMSS)就不能被发送, 直到所有的在传数据都收到ACK并且, 在收到ACK后, TCP需要收集这些小数据, 将其整合到⼀个报⽂文段中发送。

迫使TCP遵循停等( stop-and-Wait)规程⼀只有等接收到所有在传数据的ACK后才能继续发送。
该算法的精妙之处在于它实现了⾃时钟( self-clocking) 控制: ACK返回越快, 数据传输也越快。在相对高延迟的广域⽹网中, 更需要减少微型报的数⽬目, 该算法使得单位时间内发送的报⽂文段数目更少。也就是说, RTT控制着发包速率。
  • 流量控制与窗口管理

      当TPC通信的接收方的接收速度无法匹配发送速度时,发送方会降低发送速度。
      TCP的流量控制机制完成了对发送速率的调节,它是基于ACK数据包中的通告窗口大小来实现的。
      这种方式提供了明确的接收方返回的状态信息,避免接收方缓存溢出。
    

TCP拥塞控制(Congestion Control)

路由器因无法处理高速率到达的流量而被迫丢弃数据信息的现象称为拥塞。

TCP保活机制(KeepAlive)

TCP KeepAlive是⼀种在不不影响数据流内容的情况下探测对方的⽅方式。它是由⼀个保活计时器实现的。当计时器器被激发, 连接一端将发送一个保活探测(简称保活) 报文, 另⼀一端接收报⽂的同时会发送⼀个ACK作为响应。

  • TCP KeepAlive的作用

保活功能一般是为服务器器应用程序提供的, 服务器应用程序希望知道客户主机是否崩溃或离开, 从而决定是否为客户端绑定资源。

利用TCP保活功能来探测离开的主机, 有助于服务器与⾮交互性客户端进行相对短时间的对话, 例如, Web服务器、POP和IMAP电子邮件服务器器。短时间内一般网络稳定,且在相对短时间内一般能操作完。当操作完后,所以即使网络抖动原因,被keepalive断开连接,影响不大。

而更多地实现⻓时间交互服务的服务器可能不希望使用保活功能, 如ssh和Windows远程桌面这样的远程登录系统。需要长时间操作的,不希望断开连接,即使有网络抖动。

  • KeepAlive报文序列号