目录
运输层协议概述
复用和分用:网络层与运输层的关系是复用和分用的关系,即两个主机间的网络层的分组可以包括若干对运输层进程(用端口号区分)之间传输的分组。
端到端:运输层解决端到端
的通信问题,而不是点到点
的问题。如端到端的可靠传输、数据流量控制等。
TCP/IP体系中的运输层
运输层中的两个协议
TCP/IP的运输层有两个不同的协议
(1)用户数据报协议UDP(User Datagram Protocol)
(2)传输控制协议TCP(Transmission Control Protocol)
其中:
运输协议数据单元TPDU(Transport Protocol Data Unit)。但在TCP/IP体系中,则根据所使用的协议是TCP或UDP,分别称之为TCP报文段(segment)和UDP数据报(Datagram)。
UDP在传送数据之前不需要先建立连接(面向无连接)。
TCP则提供面向连接的服务(含有建立和释放连接、应答、超时重传等机制)。
TCP报文段是在运输层的端到端抽象的逻辑信道中传送,但TCP连接是可靠的全双工信道,不涉及到互连网中的路由器。
端口的概念
UDP和TCP都使用了与应用层接口处的端口(port)与上层的应用进程进行通信。没有端口就无法区分开应用层的不同进程。
端口类型:
(1)熟知端口(well-known port),其数值一般为O–1023, 例如,FTP用21,TELNET用23,SMTP用25,DNS用53,HTTP用80,SNMP用161,等等。
(2)一般端口,用来随时分配给请求通信的客户进程,>=1024。
(3)一个连接由它的两个端点来标识。这样的端点就叫做插口(socket),或套接字。插口包括IP地址(32bit)和端口号(16bit),共48bit。
(4)在整个因特网中,在运输层通信的一对插口必须是惟一的。
而标识一个连接要有4个要素:两个IP地址,两个端口号。如图中的SMTP(简单邮件传输协议)的传输
例如:上图中的连接1的一对插口是: (131.6.23.13: 1500)和(130.42.85.15: 25)而连接2的一对插口
是: (131.6.23.13: 1501)和(130.42.85.15: 25)
TCP和UDP
UDP
UDP: 虽然在相互通信的两个进程之间没有一条虚连接,但同样使用插口的概念,一个客户进程和一个服务器进
程之间也使用一对插口。
ps:使用UDP的应用层协议也可能需要可靠传输,需要时由应用层自己保证
UDP数据报就是长这样子:
比较,如图:为何IP数据报的校验和是对首部进行校验,而链路层是对整个帧进行校验,UDP是对整个PDU进行校验?
(1)路由器链路层的校验由硬件完成,不需要CPU的开销,速度很快。网络层的校验要由CPU进行,由于路由器转发的工作量很大,如果
对整个数据包进行校验,延时会很大。
(2)传输层的校验由两端的主机进行,数据包并不多,因此不会造成太大延时,所以运输层一般进行整个数据包的校验。
传输控制协议TCP
TCP报文段的首部
各数据含义:
(1)TCP报文的数据部分可以一部分是普通数据,一部分是紧急数据,“紧急指针” 指向紧急数据的最后一个字节。
(2)TCP报文的首部长度不确定,“数据偏移”字段用来说明数据部分从哪里开始。
(3)接收方可根据自己的接收缓冲区大小控制发送方发送窗口的大小。避免因发送太快造成数据丢失,起到流量控制作用。
(4)数据偏移:单位是32 bit
(5)紧急比特URG(URGent):当URG=1时,表明此报文段应尽快传送(相当于高优先级的数据)
(6)紧急指针:指出在本报文段中的紧急数据的最后一个字节的序号。
(7)确认比特ACK:只有当ACK=1时确认序号字段才有意义。当ACK=0时,确认序号没有意义。
(8)急迫比特PSH(PUSH):当PSH=1时,表明请求远地TCP将本报文段立即传送给其应用层,而不要等到整个缓存都填满了后再向上交付。
从TCP层到IP层
TCP的编号与确认
(1)TCP不是按传送的报文段来编号。TCP将所要传送的整个报文(这可能包括许多个报文段)看成是一个个字节组成的数据流,然后对每一个字节编一个序号。
(2)在连接建立时,双方要商定初始序号。
(3)TCP的确认是对接收到的数据的最高序号(即收到的数据流中的最后一个序号)表示确认。但返回的确认序号是已收到的数据的最高序号加1,表示期望下次收到的第一个数据字节的序号。
(4)TCP能提供全双工通信, 每一方都不必专门发送确认报文段,而可以在传送数据时顺便把确认信息捎带传送。
TCP传输中的问题及解决办法
(1)逐个字符发送情况下TCP传送效率不高的问题:
一个交互式用户A使用一条TELNET连接(运输层为TCP协议),与远地主机B通信。设 A 只发一个字符。加上20字节的首部后,得到21字节长的TCP报文段。再加上20字节的IP首部,形成41字节长的IP数据报,A–>B。在接收端 B, TCP发出确认,构成的数据报是40字节长,B --> A若用户要求远地主机 B 回送这一字符, B 回送41字节长的IP数据报, B --> AA 发出确认,构成的数据报是40字节长,A --> B
结论:用户仅发一个字符,线路上就需传送总长度为162字节共4个报文段(包括用户端对回送字符的确认)。
因此应适当推迟发回确认报文,并尽量使用捎带确认的方法。
解决办法(Nagle算法
):
(1)若数据是逐个字节地到达发送端,则发送端就将第一个字符先发送出去,将后面到达的字符都缓存起来。当收到对第一个字符的确认后,再将缓存中的所有字符装成一个报文段发送出去,同时继续对到达的字符进行缓存。
(2)只有在收到确认后才继续发送下一个报文段。当字符到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。
(3)算法还规定,当到达的字符已达到窗口大小的一半或已达到报文段的最大长度时,不用等待确认,就立即发送下一个报文段。
(4)但有时不宜采用Nagle算法。例如在因特网上使用 ,并将鼠标移动的信息传到远地主机。若采用Nagle算法会使用户感到无法忍受。这时最好关闭这个算法。
(2)糊涂窗口综合症(silly window syndrome),也会使TCP的性能变坏。设想这种情况:
(1)主机 A 接收端的缓存已满,而 A 的交互式的应用进程一次只从缓存中读取一个字符(这样就在缓存产生1个字节的空位子),然后向发送端 B 发送确认,并通知窗口为1个字节(但发送的数据报是40字节长), A–>B 。接着,发送端 B 又发来1个字符(但发来的数据报是41字节长), B --> A 。接收端A 发回确认, A–>B,仍然通知窗口为1个字节。这样进行下去,使网络的效率很低。
糊涂窗口综合症的解决办法
:
可让接收端等待一段时间,使得缓存或者已能有足够的空间容纳一个最长的报文段,或者已有一半的空间处于空的状态。
只要出现这两种情况之一,就发出确认报文,并向发送端通知当前的窗口大小。
此外,发送端也不要发送太小的报文段,而是将数据积累成足够大的报文段,或达到接收端缓存的空间的一半大小。
TCP的重发与确认
(1)发送方在规定的设置时间内没有收到确认,就要将未被确认的报文段重新发送。
(2)接收方若收到有差错的报文段,则丢弃此报文段(不发送否认信息)。
(3)若收到重复的报文段,也要将其丢弃,但要发回(或捎带发回)确认信息。
(4)若收到的报文段无差错,只是未按序号,那么应如何处理? TCP对此未作明确规定,而是让TCP的实现者自行确定。或者将不按序的报文段丢弃,或者先将其暂存于接收缓存内,待所缺序号的报文段收齐后再一起上交应用层。
TCP的流量控制
(1)TCP采用可变发送窗口的方式进行流量控制。窗口大小的单位是字节。
(2)发送窗口在连接建立时由双方商定。在通信的过程中,接收端可根据自己的资源情况,随时动态地调整自己的接收窗口(可增大或减小),然后告诉对方,使对方的发送窗口和自己的接收窗口一致。这种由接收端 控制 发送端的做法,在计算机网络中经常使用。
如下的窗口实例:发送端要发送的数据共9个报文段,每个报文段100字节长,而接收端许诺的发送窗口为500字节。
如下:设主机A向主机B发送数据。双方商定的窗口值是400。再设每一个报文段为100字节长,序号的初始值为1。
TCP的重传机制
数据链路层和运输层的往返时延的概率分布图
流程如下:
(1)TCP每发送一个报文段,就设置一次计时器。
(2)TCP采用了—种自适应算法。这种算法记录每一个报文段发出的时间,以及收到相应的确认报文段的时间。这两个时间之差就是报文段的往返时延。
(3)每测量到一个新的往返时延样本T1,就按下式重新计算一次平均往返时延T:
T = a * T + (1—a) * T1
在上式中,0≤a<1若a很接近于1,表示新算出的往返时延T和原来的值相比变化不大,而新的往返时延样本的影响不大(T值更新较慢)。若选择a接近于零,则表示加权计算的往返时延T受新的往返时延样本的影响较大(T值更新较快)。典型的a值为7/8。
计时器设置的重传时间(即超时时间)应大于上面得出的平均往返时延,即:
TOUT = b * T
这里: TOUT — 超时时间, T — 平均往返时延, b — 大于1的系数。TCP原先的标准推荐将b值取为2。
往返时间的测量,实现起来相当复杂。
试看下面的例子。
A在时刻t1发送出一个报文段X,重传时间到了,还没有收到确认。于是重传此报文段,该重发报文段记为Y,后来在时刻t2收到了确认报文段Z。现在的问题是:如何判定此确认报文段 Z 是对原来的报文段 X 的确认,还是对重传的报文段 Y 的确认?
(1) 由于重传的报文段和原来的报文段完全一样,因此源站在收到确认后,就无法做出正确的判断:
(2) 若收到的确认 Z 是对重传报文段 Y 的确认,但却被源站当成是对原来的报文段 X 的确认,那么这样计算出的往返时延样本
(t2-t1)和重传时间就会偏大。
(3)若收到的确认是对原来的报文段 X 的确认,但被当成是对重传报文段 Y 的确认,则由此计算出的往返时延样本(t2-t1)和重传时
间都会偏小。
解决办法
Karn提出了一个算法:在计算平均往返时延时,只要报文段重传了,就不采用其往返时延样本。这样得出的平均往返时延和重传时间当然就较准确。
但是,这又引起新的问题。
设想出现这样的情况:报文段的时延突然增大很多。因此在原来得出的重传时间内,不会收到确认报文段。于是
就重传报文段。但根据Karn算法,不考虑重传的报文段的往返时延样本。这样,重传时间就无法更新。
因此要对Karn算法进行修正。方法是:报文段每重传一次,就将重传时间增大一些:
新的重传时间 = y * (旧的重传时间),系数y的典型值是2