运输层主要负责 众端口到网络IP服务 之间的多路复用(multiplexing)与多路分解(demltiplexing):sockets to IP to sockets
套字节(socket)用端口号来指示,它是一个16bit的数(0-65535),其中 0-1023 为周知端口号
网络层分组在UDP中被称为数据报,而在TCP中被称为报文段
仅仅对分组标识一下端口号,做好多路复用与分解,附加数据的长度和检验和就发给网络层。对于其他什么都不管。
IP层仅仅提供尽力而为的服务,我们需要在端到端提供可靠性保障。在IP层传输过程中可能出现两种错误:比特差错和丢包。通过以下三种机制提供可靠的传输协议:
// RTT均值: EstimatedRTT = (1-a)·EstimatedRTT + a·SampleRTT // RTT偏差: DevRTT = (1-b)·DevRTT + b·|SampleRTT-EstimatedRTT| // 超时间隔: TimeoutInterval = EstimatedRTT + 4·DevRTT // 每当超时事件出现时:TimeoutInterval = 2·TimeoutInterval
在停等版本的协议基础上,可以采用流水线化的传输方式,将一个窗口中的数据成组发送出去,不再一个一个的传输,以提高宽带利用率。当窗口前部收到ACK将移动窗口,发送新的待发送分组。这里注意rdt与TCP对窗口的组织是不一样的,因为rdt与TCP窗口中的内容有所区别:
同时这里也面临另一个问题,对于这一窗口中的分组,有两种处理方式:是累积地处理(及对于)还是选择性的处理窗口中的分组。
协议 | 反馈 | 重传 | 定时 |
---|---|---|---|
rdtGBN | 累积确认 | 全部重传 | 仅需对窗口底部分组定时 |
tdtSR | 选择确认 | 选择没有确认的分组重传 | 对每个包单独定时 |
TCP | 累积确认 | 选择窗口最底部的那个分组重传 | 仅对最后确认的包定时 |
发送方维护一个指示接受方接收窗口(receive window)的空闲空间量rwnd来控制流量,以保证已分配的缓存不会溢出.
未被确认数据量 LastByteSent-LastByteAcked <= rwnd
通过发送方拥塞窗口(congestion window),表示为cwnd.一般运行过程中,主要有两个重要的事件:3个冗余ACK和超时。
未被确认数据量 LastByteSent-LastByteAcked <= cwnd
dupACKcount == 3
重传分组并进入快速恢复状态
ssthresh = cwnd/2
cwnd = ssthresh + 3MSS cwnd = ssthresh + 3MSS
timeout
重传分组并进入慢启动状态
ssthresh = cwnd/2
cwnd = 1
dupACKcount = 0 dupACKcount = 0
注意!
- TCP是全双工的,TCP双方都要做流量和拥塞控制;
- TCP的发送窗口大小受rwnd和cwnd两个量控制,rwnd是上限,cwnd动态变化。
三次握手:
客户主机随机选择一个序号作为检验码并请求连接,发出SYN请求报文
服务器根据SYN请求报文内容Hash计算SYN cookie,作为检验码,回填SYN请求报文的检验码为请求码,返回SYNACK报文
客户机收到SYNACK报文,为TCP连接分配资源,当以有数据时可以附加数据,设置请求码为cookie+1发送报文,发出数据报文
服务器主机检验请求码是否合法(请求码==cookie+1),合法则分配连接相关资源,TCP连接建立
双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认
四次挥手:确认方需要处理关闭连接相关事务,不能立刻关闭,TCP连接双发都可以终止该连接
UDP
TCP
仅支持单播传输
TCP的拥塞控制算法是一种分布式的异步优化算法,它趋于在竞争的多条TCP连接之间提供对一段瓶颈链路带宽的平等分享。一般情况下(即未出现超时)TCP都在拥塞避免状态和快速恢复状态之间反复跳转,呈现出"加性增乘性减"的特性,这导致TCP连接占用越多,惩罚越大,但惩罚后却都以线性递增。特别是当出现超时的时候,直接回返到慢启动状态,相当于重启连接。这保障了对瓶颈链路的公平共享。
UDP不与其他连接合作,也不适时地调整其传输速率,UDP源可能会压制TCP流量。
实际使用中通过开启多条并行TCP连接来占用更多的带宽。