TCP-IP详解笔记7
TCP-IP详解笔记7
TCP: 传输控制协议(初步)
-
使用差错校正码来纠正通信问题, 自动重复请求(Automatic Repeat Request, ARQ).
-
分组重新排序, 分组复制, 分组丢失.
-
一个直接处理分组丢失的方法是重发分组, 直到它被正确接收.
- 对方是否已经收到分组.
- 接收放接收到 的分组是否与之前发送方发送的一样.
- 接收方给发送方发信号以确定自己已经接收到一个分组, 这种方法被称为确认(acknowledgment), 或ACK.
- 发送方发送一个分组, 然后等待一个ACK. 当接收方接收到这个分组时, 它发送对应的ACK.
-
TCP 需要解决这个几个问题:
- 发送方对一个ACK应该等待多长时间?
- 如果ACK丢失了怎么办?
- 再次发送.
- 如果分组被接收到了, 但是里面有错怎么办?
-
接收方都可能接收到被传送分组的重复(duplicate)副本.使用序列号(sequence number)来处理.
-
分组窗口和滑动窗口:
- 分组窗口作为已被发送方注入但还没完成确认的分组的集合.
- 分组窗口中的分组数量被称为窗口大小(window size).
- 滑动窗口协议(sliding window).
-
变量窗口: 流量控制和拥塞控制.
- 为了处理当接收方相对发送方太慢时产生的问题, 在接收方跟不上时会强迫发送方慢下来 --- 流量控制(flow control).
- 基于速率(tate-based)流量控制, 它是给发送方指定某个速率, 同时确保数据永远不能超过这个速率发送.
- 适合流应用程序, 可被用于广播和组播发现.
- 基于窗口的流量控制(window-based), 是使用滑动串口时最流行的方法.
- 窗口大小不是固定的, 而是允许随时间而变动的.
- 接收方必须通知发送方使用了多大的窗口. --- 窗口通告(window advertisement), 或窗口更新(window update).
- 发送方可以调整窗口大小.
- 窗口更新和ACK是由同一个分组携带的, 发送方往往会和它的窗口滑动到右边的同时调整它的大小.
- 基于速率(tate-based)流量控制, 它是给发送方指定某个速率, 同时确保数据永远不能超过这个速率发送.
- 拥塞控制(congestion control)控制中间路由器中的流量.
- 拥塞控制涉及发送方减低速度以不至于压垮其与接收方之间的网络.
- 为了处理当接收方相对发送方太慢时产生的问题, 在接收方跟不上时会强迫发送方慢下来 --- 流量控制(flow control).
-
设置重传超时:
- 通过往返时间估计(round trip time estimation, RRT)去设置重传超时, 过多久才开始重传数据包.
- 对RRT进行估计.
- 通过往返时间估计(round trip time estimation, RRT)去设置重传超时, 过多久才开始重传数据包.
-
TCP的紧急机制(urgent mechansim) --- 它允许发送方指定数据流中的某些数据作为特殊数据.
-
TCP和UDP使用相同的网络层(IPv4或IPv6).
-
TCP提供了一种面向连接(connection oriented), 可靠的字节流服务.
- 在交换数据之前必须通过仙湖联系来建立一个TCP连接.
- TCP提供一种字节流抽象概念给应用程序使用. --- 没有由TCP自动插入的记录标志或消息边界.
- 一个记录标志对应着一个应用程序的写范围指示, 每个端点独立选择自己的读和写大小.
- TCP根本不会解读字节流里的字节内容, 它并不知道正在交换的数据类型.
-
TCP维持了一个强制的校验和, 该校验和涉及它的头部, 任何相关应用程序数据和IP数据报的所有字段. --- 端到端的伪头部.
-
当TCP发送一组报文时, 通常设置一个重传计时器, 等待对方的确认接收.
- 发送一个窗口只设置一个定时器.
- TCP是双工的. 数据可以向两个方向流动, 两个方向相互独立.
- 一旦建立连接, 每个报文也包含一个窗口通告实现相反反向上的流量控制.
-
因为TCP是一个字节流协议, TCP绝不会以杂乱的次序给接收应用程序发送数据,
- TCP接收端可能会被迫先保持大序列号的数据不交给应用程序, 直到缺失的小序列号的报文被填满.
TCP头部和封装
- TCP必须保持连接的每一端同步的最新状态.
- 每个TCP头部都包含了源和目的的端口号.
. - 在TCP术语中, 一个IP地址和一个端口的组合被称为一个端点(endpoint)或套接字(socket).
- 四元组: 客户机的IP地址, 客户机端口号, 服务器IP地址和服务器端口号.
- 序列号(Sequence Number)字段标识了TCP发送端到TCP接收端的数据流的一个字节, 该字节代表着该序列号的报文段数据中的第一个字节.
- 当建立一个新连接时, 从客户端发送值服务器的第一个报文端的SYN位字段被启用.
- 初始序列号(Initial Sequnence Number, ISN)不是0或1, 是一个随机值.
- TCP头部定义了8位的字段:
- CWR --- 拥塞串口减(发送方降低它的发送速率).
- ECE --- ECN回显.(发送方接收到一个更早的拥塞通告).
- URG --- 紧急.(紧急指针字段有效, 很少被使用).
- ACK --- 确认(确认号字段有效 --- 连接建立以后一般都是启用状态).
- PSH --- 推送(接收方应尽快给应用程序传送这个数据 --- 没有被可靠地实现和用到).
- RST --- 重置连接(连接取消, 经常是因为错误).
- SYN --- 用于初始化一个连接的同步序列号, 用来发起一个连接.
- FIN --- 该报文段的发送方已经结束向对方发送数据, 将要终止一个连接.
- TCP的流量控制由每个端点使用窗口大小字段来通告一个窗口大小来完成, 窗口大小由ACK号指定.(接收方想要接收的那个字节开始).
- 16位字段, 限制窗口大小为65535, 从而限制了TCP吞吐量性能.
- 最大段大小选项(MSS), 连接的每个端点一般在它发送的第一个报文段(SYN的报文段)上指定这个选项.
- MSS指定该选项的发送者在相反方向上希望接收到的报文段的最大值.
- 如果没有数据被传输, 那么一个不带任何数据的头部也会被用于确认接收的数据(称为一个纯(pure) ACK), 同时通知通信方改变窗口大小(称为一个窗口的更新(window update)).
- TCP提供一种可靠, 面向连接, 字节流, 传输层的服务.
TCP 连接管理
- TCP是一种面向连接的单播协议, 在数据发送之前, 双方必须彼此之间建立一条连接, TCP服务模型是一个字节流.
- TCP必须检测并修补所有在IP层(或下面的层)产生的数据传输问题(丢包, 重复, 错误).
- 由于需要对连接状态进行管理(通信双方都需要维护连接的信息), TCP被认为是一个比UDP更复杂的传输层协议.
- TCP需要面对一个连接何时建立, 正常地终止, 以及无警告的情况下重新启动.
- 连接的过程中, 双方需要建立一些选项, 这些选项被称为连接参数(40字节).
TCP连接的建立与终止
- 一个TCP连接由一对端点或套接字构成, 其中通信的每一端由一对(IP地址和端口)所唯一标识.
- 一个TCP连接通常分为3个阶段: 启动, 数据传输(连接已建立)和退出(关闭).
- 建立连接需要的步骤:
- 主动开启者(通常为客户端)发送一个SYN报文段(TCP头部的SYN为字段置位的TCP/IP数据包), 并指明想要连接的端口好和初始序列号, 客户端发送的这个SYN报文被称作段1.
- 服务器也发送自己的SYN报文段作为响应, 并包含了它的初始序列号, 该段被称为2.
- 为了确认客户端的SYN, 服务器将其包含的ISN(序列号)数值加1最为ACK的返回值.
- 因此发送一个SYN, 序列号就会自动加1. 如果出现丢失的情况, 该SYN就会重传.
- 为了确认服务器的SYN, 客户端将ISN(s)的数值加1作为返回的ACK数值, 称为段3.
*通过三个报文就可以完成一个TCP连接的建立(通常称为三次握手), 三次握手的目的不仅在于让通信双方了解一个连接正在建立, 还在利用数据包的选项来承载特殊的信息, 交换初始序列号(Initial Sequence Number, ISN).
- 发送首个SYN的一方被认为是主动地打开一个连接.
- 连接的任何一方都可以发起关闭连接操作. TCP还支持双方同时关闭.
- 关闭操作是因为应用程序提出关闭请求而引发(调用close()).
- TCP 规定发送FIN报文来发起关闭操作.
- 关闭的步骤为:
- 连接的主动关闭者发送一个FIN报文指定接收者希望看到字节当前的序列号(K). FIN报文还包含了一个ACK段用于确认对方最近一次发来的数据.
- 连接的被动关闭者将K的数值加1作为响应的ACK值, 以表明它已经成功接收到主动关闭者发送的FIN. 被动关闭者转换为主动关闭者, 并发送自己的FIN, 该报文的序列号为L.
- 为了完成连接的关闭, 最后发送的报文段还包含一个ACK用于上一个FIN, 如果出现FIN丢失, 发送方将重新传输直到收到一个ACK确认.
- 关闭一个TCP连接需要4个报文段.
- 7个报文段是每一个TCP连接在正常建立与关闭的基本开销.
- 初始序列号:
- 当一个连接打开时, 任何拥有合适的IP地址, 端口号, 符号逻辑的序列号以及正确校验和的报文都将被对方接收.
- TCP报文段在经过网络路由后可能会存在延迟抵达与排序混乱的情况, 选择初始序列号来解决这个问题.
- 在建立连接的SYN之前, 通信双方会选择一个初始序列号.
- 初始序列号会岁时间而改变, 每个连接都拥有不同的初始序列号.(初始序列号可以被认为是一个32位的计数器 --- 4微妙加1).
- 如果选择合适的序列号, IP地址以及端口号, 那么任何人都可以伪造出一个TCP报文段, 从而打断TCP的正常连接. 初始序列号变得相对比较难猜测, 或者加密.
- 半随机的方法选择初始序列号.
- Linux系统采用基于时钟的方案, 并对每一个连接设置随机的偏移量. 随机偏移使用加密散列函数得到.散列函数每隔5分钟改变一次.
- 半随机的方法选择初始序列号.
- TCP选项:
- TCP头部包含了许多选项
- 最大段大小指TCP协议所允许的从对方接收到的最大报文段, 通信双方在发送数据是能够使用的最大报文段.
- 最大段大小只记录TCP数据的字节数, 不包括TCP和IP头部.
- 窗口缩放选项(表示为WSCALE或WSOPT)能够有效地将TCP窗口广告字段的范围从16位增加至30位. 该选项只能出现与SYN报文段中.
- 时间戳要求发送方在每一个报文段中添加2个4字节的时间戳数值, 和时间戳回显重试字段.
- 时间戳是一个单调增加的数值.
- 时间戳选项与重传计时器的设置密切相关, 虽然时间戳允许更高频率的往返时间样本, 但放回绕序列也为避免接收旧报文段与判断报文段正确性的方法.
- J:K表示从第J个字节到第K-1个字节的数据.
- 用户超时数值指明了TCP发送者在确认对方未能成功接收数据之前愿意等待该数据ACK确认的时间.
- 认证选项使用了一个加密散列算法以及TCP连接双方共同维护的一个秘密值来认证每一个报文段.
- TCP头部包含了许多选项
TCP的路径最大传输单元发现
-
路径最大传输单元(MTU)是指经过两台主机之间路径的所有网络路径中最大传输单元的最小值.
- 有助于TCP数据报的分片.
-
TCP使用对外接口的最大传输单元的最小值. 根据通信对方声明的最大段大小选择发送方的最大段大小(SMSS).
-
路径最大传输单元不允许发送方有超过接收方最大段大小的行为.
-
11种状态名称: CLOSED_WAIT, CLOSED, LISTEN, SYN_SENT.
- TIME_WAIT状态
- TIME_WAIT状态也被称为2MSL等待状态, TCP将等待2倍最大段生存期时间(Maximum Segment Lifetime, MSL). 加倍等待. MSL也可被理解为报文段在丢弃前在网络中存在的最大允许时间.
- 当TCP执行一个主动关闭并发送最终的ACK时, 连接必须处于TIME_WAIT状态并持续两倍的最大生存期时间.
- 这样可以让TCP重新发送的最终ACK以避免丢失.
- 因为对方重传了FIN, 所以应该应答一个ACK的重传报文.
- 当一个连接处于2MSL状态时, 任何延迟到达的报文段都将被丢弃.
- 一般客户端执行主动关闭操作而会进入TIME_WAIT状态.
- 2MSL状态能够防止新的连接将前一个连接的延迟报文段既往史成自身数据的状态.
重置报文段
-
TCP头部的RST位字段置位的报文段被称作重置报文段(重置).
- 发现一个报文段对于相关连接而言是不正确的, TCP就会发送一个重置报文段.
- 重置报文段会导致TCP连接的快速拆卸.
- 针对不存在端口的连接请求;
- 终止一条连接.
- 半开连接.
- 时间等待错误.
-
大多数TCP服务器是并发的.
-
一台UDP服务器不仅能够指定本地IP地址与本地端口号, 还能够指定外部IP地址与外部端口号.
-
一个并行的服务器会为每一个客户端分配一个新的进程或线程, 这样负责侦听的服务器能够始终准备着处理下一个到来的连接请求.
-
在操作系统内部通常会有两个连接队列.
-
可以通过tcpdump和Wireshark来显示TCP协议的行为以及TCP头部字段的使用情况.
-
TCP状态转换图对理解其运行非常重要.
-
SYN泛洪是一种TCP拒绝服务攻击.