第十二章 传输控制协议TCP
12.1 引言
UDP协议能够检测接收到的数据是否有差错,但是不能纠正
纠正的意思是恢复接受道德错误数据,第二就是重新发送
主要是香农的差错校验码,和更为简单的尝试重新发送。
12.1.1 ARQ和重传
分组重新排序,分组复制,分组泯灭(丢失)
构造一个可靠的传输方式,主要要考虑:
- 对方是否已经接受到分组
接收方,接收到数据包后,发送ACK确认 - 接收到的分组是否是所需要的
判断是否重复,判断分组中的数据是否有错误。
所以,需要对每个分组编号,然后数据报中添加校验和 - 如何控制发送速率
避免接收端丢弃数据
因此引出的问题时:
- 发送方应该等待一个ACK多长时间
- ACK丢失怎么办
ACK本身不会被重传 - 分组里面有错误怎么办
直接丢失,不发送ACK,也没有ICMP - 发送速率如何控制
滑动窗口协议
每次发送出多少?发送速度
是这个样子的:
每个TCP分组到达目的主机以后,目的主机发送一个ACK确认。除了ACK确认不需要再返回ACK确认外,其他的TCP分组都需要这个确认。
源主机收到该ACK确认以后才继续发送一下个分组。
这样很慢。大部分源主机都在等待ACK。
在接收方接受速度太慢时,会强迫发送方速度慢下来。成为流量控制。
有两种方式:基于速率(发送方发送速率不超过该速率)
另一个就是基于窗口,也就是本协议。
接收方通知发送方使用多大的窗口,成为窗口通知。一般和ACK由同一分组携带。也就是在窗口滑动的同时,更新窗口大小。
所以采用这样一种方式,源主机突突突排队发送好几个分组,然后等待ACK。同时没有收到ACK的分组将会保存这些分组。
而收到ACK的分组副本就抛弃。然后发送下一个分组。
也就是永远有那么几个分组是被发送但是没收到ack的。这几个分组可以想象为在窗口中,前面的分组ack收到以后,窗口向后滑动一个分组,同时进入窗口的分组被发送出去。而窗口前面的都是收到ACK的分组,窗口之后的分组都是没有发送的分组。窗口之中的分组都是已发送但是还没有收到ACK的分组,同时分组的副本也被保存着。
而这种类型的协议就是滑动窗口协议。
滑动窗口协议12.1.3
拥塞控制涉及发送方降低速度以不至于压垮发送方和接收方之间的网络。接收方发送一个窗口通告高速发送方减慢速度。称为明确发信。另一种方法是,发送方猜测接收方的速度,然后减慢发送速度。
12.1.4 重传超时时间
发送方重发一个分组之前要等待的时间总量为:发送分组所用时间+接收方处理时间+发送一个ACK所用时间+ACK返回到发送方的时间
协议估计这段时间的长短称为往返时间估计RTT,而这个值随着时间变化。
12.2 TCP
TCP提供一种面向连接的可靠地字节流服务。
字节流
不包含边界数据的连续流!
TCP提供一种字节流抽象概念给应用程序使用。这种设计方案的结果是,没有由TCP自动插人的记录标志或消息边界。一个记录标志对应着一个应用程序的写范围指示。如果应用程序在一端写人10字节,随后写人20字节,再随后写人50字节,那么在连接的另一端的应用程序是不知道每次写人的字节是多少的。例如,另一端可能会以每次20字节分四次读人这80字节或以其他一些方式读人。一端给TCP输人字节流,同样的字节流会出现在另一端。每个端点独立选择自己的读和写大小。
12.2.2 TCP中的可靠性
TCP提供了可靠性:
tcp把发送的字节流转化为一组ip可携带的分组,称为组包。
这些分组包含序列号,序列号代表了每个分组中第一个字节,在整个字节流中的字节偏移。这允许分组在传送中是可变大小的,并且允许重新组包。
应用程序发送出去的数据,被协议打散成tcp认为最佳的大小块来发送。
TCP维持了一个强制的校验和,涉及到头部,数据和ip头部的所有段。(也是一个伪头部)
当TCP发送一组报文的时候,设置一个重传计时器,等待对方的确认接收。而且只设置一个计时器(upd分片的时候,每个分片设置一个),当ACK到达的时候,计时器被重置。
接收端接收到数据的时候,发送ACK,TCP使用积累ACK,也就是ACK不会马上发送,回合其他后面的一起。
如果一个ACK丢失,而后续序号大的ACK被接收端接收到,那么后续的ACK可以确认前面的报文段。
TCP报文
TCP报文- 两个端口号,各16bit
- 序列号 32bit
自己发送的数据,的偏移 - 确认号 32bit
用来确认对方发送数据最后一个字节+1,同时也是接收端期望收到的下一个数据包的序列号 - 头部长度 4bit
这个长度不是以bit为单位,而是以4B为单位,也就是这个字段中的数组,表明头部的长度是几个32bit(4B)
这个字段最大2^4-1=15,所以15*4=60字节。也就是TCP的头部最大60字节
这个字段不是多余的,因为TCP头部会包含可选字段。 - 保留4bit
- CWR 拥塞窗口
接收方发送给发送方,请求发送方降低发送速率 - ECE
在数据报途径的路径中,某个路由器阻塞,就会设置这个位。被接收方或者发送方看到。 - URG 紧急
很少使用 - ACK
指明这个数据包是一个ACK包。是指明这个包含ACK,也可能包含数据的。 - PSH 推送
接收方应尽快给应用程序传送这个数据。
没有被很好的实现 - RST 重置数据包
嗯,用来终止一个连接的。 - SYN 初始画一个连接的同步序列号
这个位指明,这个数据报是建立连接的数据报 - FIN
该报文段的发送方已经结束向对方发送数据。 - 窗口大小
TCP流量控制由每个端使用窗口大小来通告一个窗口大小来完成。
这个窗口是字节数,从ACK号指定,也是接收方想要接收到的那个字节开始。
也就是ACK前面的都是连续的。 - TCP校验和
和CRC的校验机制一样。 - 紧急指针
这个字段只有URG 字段被设置时才有效。
这个指针时一个必要时加到报文段的序列号上的偏移,可以产生紧急数据的最后一个字节的序列号
目的是:让发送方给另一端提供特殊标志数据的方式。
选项
最常见的选项是最大段大小MSS。
连接的每个端一般在她发送的第一个报文段上指明这个选项,指明发送方在希望接收到的数据段的最大值。