第17章TCP:传输控制协议
面向连接的、可靠的字节流服务
TCP的可靠性表现的方方面面:
(1)应用程序数据切割成TCP认为最适合发送的数据块
(2)超时重传
(3)对收到的数据进行确认
(4)首部和数据部分的检验和,错误则丢弃,进行重发
(5)对接收到的数据进行排序,然后交给应用层
(6)TCP丢弃重复的数据
(7)流量控制,避免接收端缓冲区溢出
字节流服务:不在字节流插入记录标识符
TCP对字节流不进行解释,由应用层解释
18章TCP连接的建立与终止
一端为建立连接而发送SYN,ISN为连接选择一个初始序号。ISN随着时间的变化而变化,这样也就可以使得每个连接具有不同的ISN。这样做是为了避免网络延迟的分组在以后传送到达目的网络,而导致目的方对这个报文做出错误处置
连接建立超时
当服务器处于异常状态,客户端发送连接请求,试图建立连接会出现下列的情况。客户端发送SYN,由于没有收到服务器的应答,客户端会隔一定时间再次发送SYN,直到从发送第一个SYN到现在有规定的时间后,则会放弃连接
最大报文段的长度
当一个连接建立时,连接双方需要通告各自的MSS
TCP的半关闭
半关闭,是指TCP连接的一端结束了他的发送后还能够接收另一端数据的能力。只有很少的应用程序使用半关闭。在应用程序中不是调用close而是调用shutdown,而第2个参数为1,则插口的API支持半关闭。
11个状态转换
与netstat命令显示的状态名称一致
time_wait 2MSL等待状态。MSL报文段最大生存时间。在这个等待期间,任何迟到的报文都将被丢弃。
终止一个已经建立连接的服务器程序,如果试图立即重启这个服务器程序,不能把这个数值端口复制给它的端口,因为那个端口正处于2MSL阶段,这个过程需要1-4分钟的时间
复位报文段
一个报文段发往基准的连接出现错误,TCP会发出一个复位报文段
基准连接:目的IP目的端口以及源IP源端口指明的连接
1.到不存在的端口的请求连接
当连接请求到达时,目的端口没有进程正在监听
当UDP出现这种情况,会产生一个ICMP端口不可达的信息
2.异常终止一个连接
发送一个复位报文段而不是FIN中途释放一个连接,这种称为异常释放
异常终止对于应用程序的优点:
(1)丢弃任何待发送数据,立即发送复位报文段
(2)RST接收方会区分另一端是正常还是异常关闭。
需要注意的是RST报文段不会导致另一端产生任何响应,另一端根本不进行确认。收到RST的一方将终止该连接,并通知应用层连接复位。
检测半打开连接
半打开:如果一方已经关闭或异常终止而另一方不知道。只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异常。
半打开连接的另一个常见原因是当服务器主机突然掉电而不是正常的结束服务应用程序后再关机,服务器主机重启后,客户向服务器发送另一行字符。由于服务器 的TCP已经重新启动,它将丢失复位前连接的所有信息,因此它不知道数据报文段中提到的连接。TCP的处理原则是接收方以复位作为应答。客户收到复位报文段表示连接已被另一端的主机终止
同时打开
两个应用程序彼此执行主动打开,每一方都使用一个对方熟知的端口作为本地端口
TCP在处理同时打开,仅建立一条连接而不是两条连接。同时打开的连接需要交换4个报文段,比正常的握手多一个报文段。要注意没有将任何一端称为客户或者服务器,每一端既是客户又是服务器
同时关闭
TCP选项
第19章 TCP的交互数据流
TCP报文段有些包含成块数据,有些包含交互数据
Rlogin连接上键入一个交互命令产生的数据流。每一个交互按键会产生一个数据分组。
一般可以将报文段2和报文段3合并,这种合并技术称为经受时延的确认
经受时延的确认
通常TCP在接收到数据并不会立即发送ACK,它会推迟发送,使得ACK与需要沿这个方向发送的数据一起发送。绝大多数采用采用时延为200ms,也就是最多等待200ms看是否有一起发送的数据。
Nagle算法
这个算法要求TCP连接上最多只能有一个未被确认的未完成的小分组,这个分组确认未到达之前不能发送其他分组。而TCP收集这些小分组,并在确认到来时以一个分组的方式发送出去。
这个算法是自适应的,确认到达的越快,数据就发送的越快
在较慢的广域网环境中,通常使用Nagle算法减少这些小报文段的数目,这个算法限制发送者任何时候只能有一个发送的小报文段未被确认
关闭Nagle算法,当消息需要无时延发送
第20章 TCP的成块数据流
tcp接收方对收到的报文段进行确认,有一个时延定时器,当时延定时器溢出时,接收方发送对已经收到的报文段发送确认
前面的三个例子都表现了滑动窗口和累计确认
PUSH标志
发送方使用这个标志就是通知接收方将所收到的数据全部提交给接收进程。这里的数据包括与PUSH一起传送的数据以及接收方TCP已经为接收进程收到的其他数据
当服务器端收到这个标志的报文段,需要立即将数据递交给服务器进程而不是等待是否还会有额外的数据到达。
伯克利的实现一般不将接收方收到的数据推迟提交给应用程序,因此他们忽略所接受的PUSH标志
慢启动
发送方一开始就发送多个报文段,知道达到窗口大小。这种方式适用于发送方和接收方处于同一个网络情况下。而在发送方和接收方中间有多个路由器个速率较慢的链路的情况下,可能会出现问题,一些中间路由要缓存分组,又可以会耗尽存储器的空间。
这种算法使得新分组进入网络的速率与另一端的返回确认速度一致工作
慢启动增加了一个窗口拥塞窗口cwnd。拥塞窗口被初始化为1,每当接收到一个ACK,拥塞窗口就增加一个报文段。这种增长方式指数增长。发送方取拥塞窗口与通告窗口的最小值作为上限。
拥塞窗口是发送方的流量控制,通知窗口是接收方使用的流量控制。
成块数据的吞吐量
紧急方式
一端告诉另一端有些具有某种方式的紧急数据已经放置在普通的数据流中。另一端被通知这个紧急数据已经被放置在普通数据流中,有接收方决定如何处理
URG=1,16位的紧急指针放置了一个偏移量,是TCP首部中序号与紧急数据相加
* 第21章 TCP的超时和重传*
重传定时器,保活定时器,坚持定时器,2MSL定时器
21.2超时和重传的简单例子
第一个定时不准确的原因:TCP采用500ms的定时器,但是第一个500ms终止的时间是随机,这也导致了第一个定时不准确
拥塞避免算法
是一种处理丢弃分组的方法,有两种分组丢失的指示,发生超时和接收到重复确认
分组丢失:由于分组损坏引起的丢失非常少,由于网络上的拥塞引起的较大
拥塞避免和慢启动算法:
一个拥塞窗口和一个慢启动门ssthresh
工作过程:
初始化cwnd=1个报文段,ssthresh=65535字节
输入不能超过cwnd和接收方通知窗口。
当拥塞发生时,ssthresh设置为当前窗口的一半(cwnd和通知窗口的最小值,最少为2个报文段),如果是由于超时引起的拥塞,cwnd设置为1
当新的数据被确认时,增加cwnd。如果cwnd小于等于ssthresh,正在进行慢启动,否则就在拥塞避免
慢启动算法每次收到一个ACK将cwnd+1
拥塞避免算法要求每次收到一个确认将cwnd+1,是一种加性增长
快速重传和快速恢复算法
重复ACK原因:丢失报文段引起的,失序的报文段
在重新排序的报文段被处理并产生一个新的ACK之前,只可能产生1-2个重复的ACK。如果一连串收到3及以上的重复ACK,非常可能是报文段丢失了
就重传丢失的报文段不需要等到时延定时器溢出,这就是快速重传,接下来执行的不是慢启动而是拥塞控制算法就是快速恢复算法
在重传后没有执行慢启动的原因:由于收到了重复的ACK,说明两端之间还有数据流动,不想执行慢启动来突然减少数据流
过程:
收到第3个重复的ACK时,将ssthresh设置为cwnd的一半,重传丢失的报文段。cwnd为ssthresh加上3倍的报文段大小
每次收到另一个重复的ACK,cwnd+=1/cwnd并发送一个分组(如果新的cwnd能够发送)
当一个新的ACK到达,设置cwnd为ssthresh。这个ACK应该是在进行重传后的一个往返时间内对步骤1重传的确认。
分组丢失时,将速率降为以前的一半
ICMP差错
常见的ICMP差错就是源站抑制,主机不可达和网络不可达
实现对这些错误的处理:
接收到源站抑制,引起cwnd=1的设置,发起慢启动
重新分组
当TCP超时重传时,不一定要重传同样的报文段,允许进行重新分组发送一个较大的报文段。
第22章 TCP的坚持定时器
当窗口为0,更新窗口的报文丢失的情况下:接收方等待接收数据,发送方等待更新窗口的报文。为了避免这种死锁情况,发送方使用了一个坚持定时器周期性地向接收方查询,以便发现窗口是否已经增大
坚持定时器使用普通TCP指数退避
窗口探查包含一个字节的数据,返回窗口为0的ACK并不是确认这个字节,因此这个字节被持续重传
糊涂窗口综合征
少量的数据将通过连接进行交换,而不是满长度的报文段
这种现象可发生两端的任何一端:接收方通知一个小的窗口,发送方发送少量的数据
采取措施避免:
接收方不通告小窗口:通常的算法是接收方不通告比当前窗口大的窗口除非窗口可以增加一个报文段,或者可以增大接收缓存空间的一半
发送方避免:可以发送一个满长度的报文,发送至少是接收方通告窗口一半大小的报文,可以发送任何数据并且不希望接收ACK
当发送方发送FIN到收到ACK后,不设置定时器了
第23章 TCP的保活定时器
保活功能主要由服务器的应用程序提供,如果客户已经消失,使得在服务器上存在一个半开放连接,服务器等到这客户发送数据。保活功能就是试图在服务器端检测到这种半开放连接
服务器向客户端发送探查报文段,客户主机必须处于以下情况之一:
(1)客户主机依然正常运行,并从服务器可达
(2)客户主机已崩溃,关闭或者正在重启。服务器收不到对探查的回应。多次发送探查报文,没有收到响应,则认为主机已经关闭并终止连接
(3)客户主机崩溃并已重启。服务器将收到响应,但是这个响应是复位,服务器终止这个连接
(4)客户主机正常运行,但是从服务器不可达。这与(2)相同,TCP不能区分这两种情况