一、传输层的服务基本原理
1.多路复用和解复用(分路)技术
复用是指:发送方的不同的应用进程都可以使用同一个传输层协议传送数据;
分路技术是指:接收方的传输层剥去报文首部之后能把这些数据正确的传输到正确的应用进程上。
2.可靠数据传输
3.流量控制和拥塞控制
二、传输层提供的服务
2.1传输层寻址和端口
传输层主要是提供不同主机上的进程之间的逻辑通信(端到端的通信),即使在不可靠的网络层(主机之间的逻辑通信)传输下,传输层也能提供可靠的传输。(所谓的逻辑通信就是指:传输层之间看似是在水平方向传送数据,但是事实上这两个传输层之间并没有水平方向上的物理连接)
传输层的寻址最重要的就是进程的端口号了。那么什么是端口和端口号呢?
端口简言之就是为其临近层的应用层的各个应用进程的数据通过这个“门”向下传递给传输层,反过来呢就是让传输层知道接受到的报文数据如何正确传递交付到对应的应用层上的进程上。
端口号就是用来标识应用进程的数字标识。其端口号的长度为16Bit;也就是能够标识2^16个不同的端口号。另外端口号根据端口范围分为2类。
1.服务端使用的端口号:1、熟知端口号:0-1023范围。由IANA(互联网地址指派机构分配给TCP/IP最重要的一些应用进程,为固定格式)。2、登记端口号:1024-49151为没有熟知端口号的应用程序使用的,需要给IANA注册登记,防止重复。
常见的熟知端口号:
应用进程 | FTP | TELNET | SMTP | DNS | TFTP | HTTP | SNMP |
---|---|---|---|---|---|---|---|
端口号 | 21 | 23 | 25 | 53 | 69 | 80 | 161 |
2.客户端使用的端口号:数值范围为49152-65535.也叫作短暂端口号。是在客户端进程运行成功后动态选择的。
另外需要注意 是端口号只具有本地意义,即端口号只是标志本地计算机应用层的各进程。在因特网中,不同的计算机的相同端口号是没有联系的。
补充:套接字(socket)。我们知道在网络中通过Ip来唯一标识一个主机。而通过端口号来标识一台主机中的不同应用进程。所以在网络连接中就出现了Socket套接字来标识一个主机上的某进程。其实际是一个通信端点。
套接字(Socket) = (Host IP , port)
2.2无连接服务和面向连接服务
面向连接和无连接服务的区别在于在通信双方通信之前,是否需要先建立连接。换句话说就是,通信双方之间的数据传输是否基于双方需要建立连接。那么,面向连接就是在双方通信之前,必须建立连接,在通信过程中,整个连接的过程一直被监控和管理,在通信结束之后,则释放这个连接。相反,无连接服务是。两个实体之间的通信不需要建立好连接,需要通信时,直接将信息发送到“网络”上,让该信息在网上尽力传输到目的方。
在TCP/IP协议簇中,在IP层中使用了这两种协议服务。其中TCP提供面向连接的可靠的传输服务,它不提供广播和组播机制,包括了确认-重传机制、流量控制、计时定时器、连接管理等等。这一方面使得TCP连接适用在可靠性高的传输场合,如HTTP何FTP、TELNET等 。但是,另一方面呢就是也因此增加了开销。例如数据报的报头增大。
UDP协议是非连接的不可靠传输机制。它在Ip之上仅提供了多路复用和数据差错检查服务。由于UDP服务不需要建立连接,执行速度快,实时性好,只要用于小文件的传输协议*(DNS,SNMP,RTP,TFTP)
补充:
1.IP数据报和UDP数据报的区别:IP数据报在网络层要经过路由的存储转发;而UDP数据报是在传输层的端到端的逻辑信道中传输,而封装成IP数据报在网络传输中,UDP数据报对于路由是不可见的。
2.TCP和网络层的虚电路的区别:TCP报文段在传输层抽象的逻辑信道中传输,对路由器不可见;虚电路所经过的交换节点都必须保存虚电路状态信息。在网络层若采用虚电路方式,则无法提供无连接服务;而传输层采用TCP协议不影响网络层提供无连接服务。
三、UDP协议
3.1UDP的首部格式
UDP数据报有两个部分组成,分为UDP首部和用户数据。首部部分有8个字节,4个2字节的字段组成,整个UDP数据报作为IP数据报的数据部分封装在IP数据报中。其UDP数据报组成图解如下:
其中checkSum校验和表示简单的校验和来进行差错检测。有错就丢弃。该字段是可选的。
以下是UDP数据报首部和伪首部(12位,为了计算检验和)和IP数据报的图解
伪首部仅仅是为了计算校验和,而不进行传送和递交服务。这样的校验和,既检查了UDP数据报,
又同时对IP数据报的源IP地址和目的IP地址进行了校验。
四、TCP协议
TCP协议只要解决传输的可靠、有序、无丢失和不重复的问题,它主要特点是:
1.是面向连接的传输层协议。
2.是端对端的,只能是一对一连接。
3.可靠的交付服务。无差错、无重复、且有序。
4.面向字节流
4.1、TCP报文报
同样的,TCP数据报分为数据首部和TCP数据两部分。其首部格式图解:
字段解释:
序列号:
ACKs:
五、可靠数据传输的基本原理:
可靠数据传输的基本结构-接口
3.可靠传输协议Rdt版本
3.1、rdt1.0
基本特性:
3.2、Rdt2.0(引入差错控制-接收发送反馈-重传机制)
下面是Rdt2.0下的有限状态机的简图表示:采用停等协议
我们再看看当通信中无错误存在下的有限状态机FSM的简图
下面是有错误存在的FSM简图
总结:在rdt2.0中我们很好的引入了检验和来检验差错,同时引入ACK和NAK进行反馈给发送方,告知接收是否成功,如果不成功发送NAK给sender,sender重传。但是我们考虑:如果反馈信息ACK和NAK存在错误呢?那么发送方收到的反馈就是错误的或者接收不到呢?所以引入rdt2.1
Rdt2.1的sender和rev方对Rdt2.1的有限状态机表示:Sender
Receiver2.1
总体来说Rdt2.1相比,具有以下改进:
我们可以发现在Rdt2.1中,我们只是针对ACK进行了检验,加入了序列号解决分组重传重复问题,那么NAK就不需要了,所以Rdt2.2的做法就是不采用NAK。
我们再考虑到如果传输信道极可能发生错误吗,也可能发生分组丢失,那么Rdt2.2上采用的“序号+检验和+ACK+重传机制就不能实际解决问题了。那么也就出现了Rdt3.0,引入定时器”
rdt3.0举例:
六、TCP连接管理:
TCP是面向连接的,所以每一个TCP都会有三个阶段状态:连接建立、数据传送、连接拆除。连接管理就是使运输连接的建立和释放都正常运行。
6.1、TCP的连接建立
典型的“三次握手”:
当客户端向服务器发起连接请求时,客户端会发送同步序列标号SYN
到服务器,在这里我们设SYN
为m,等待服务器确认,这时客户端的状态为SYN
_SENT。
当服务器收到客户端发送的SYN
后,服务器要做的是确认客户端发送过来的SYN
,在这里服务器发送确认包ACK
,这里的ACK
为m+1,意思是说“我收到了你发送的SYN
了”,同时,服务器也会向客户端发送一个SYN
包,这里我们设SYN
为n。这时服务器的状态为SYN
_RECV。在此时,服务器为该TCP连接分配TCP缓存和变量。服务器资源在此时分配(而客户端在第三次完成时才分配资源)。记录了客户端的请求信息,如果没有收到来自客户端的第三次回话,就会在一段时间内缓存TCP信息,这也是黑客攻击服务器的SYN洪泛攻击
一句话,服务器端发送SYN
和ACK
两个包。
客户端收到服务器发送的SYN
和ACK
包后,需向服务器发送确认包ACK
,“我也收到你发送的SYN
了,我这就给你发个确认过去,然后我们即能合体了”,这里的ACK
为n+1,发送完毕后,客户端和服务器的状态为ESTABLISH,即TCP连接成功。
在三次握手中,客户端和服务器端都发送两个包SYN
和ACK
,只不过服务器端的两个包是一次性发过来的,客户端的两个包是分两次发送的
6.2、TCP连接的释放
典型“四次挥手”
当A端和B端要断开连接时,需要四次握手,这里称为四次挥手。
断开连接请求可以由客户端发出,也可以由服务器端发出,在这里我们称A端向B端请求断开连接。
A端向B端请求断开连接时会向B端发送一个带有FIN
标记的报文段,这里的FIN
是FIN
ish的意思。
B端收到A发送的FIN
后,B段现在可能现在还有数据没有传完,所以B端并不会马上向A端发送FIN
,而是先发送一个确认序号ACK
,意思是说“你发的断开连接请求我收到了,但是我现在还有数据没有发完,请稍等一下呗”。
当B端的事情忙完了,那么此时B端就可以断开连接了,此时B端向A端发送FIN
序号,意思是这次可以断开连接了。
A端收到B端发送的FIN
后,会向B端发送确认ACK
,然后经过两个MSL时长后断开连接。
MSL是Maximum Segment Lifetime,最大报文段生存时间,2个MSL是报文段发送和接收的最长时间。
四次挥手图解
TCP连接管理总结:
1、连接建立
2、连接释放
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
如上图所示A向B发送数据。在连接建立时,B告诉A接收窗口rwnd(receiver window)= 400,单位字节,因此发送方A的发送窗口不能400。
(可以看出,B向A发送的三个报文段都设置了 ACK = 1以保证字段有效,后面的rwnd值就是接收方对发送方的三次流量控制。)
第一次把窗口设置为300 ,第二次100 ,最后一次为 0,即不允许发送方再发送数据的状态。
但是当某个ACK报文丢失了,就会出现A等待B确认,并且B等待A发送数据的死锁状态。为了解决这种问题,TCP引入了持续计时器(Persistence timer),当A收到rwnd=0时,就启用该计时器,时间到了则发送一个1字节的探测报文,询问B是很忙还是上个ACK丢失了,然后B回应自身的接收窗口大小,返回仍为0(A重设持续计时器继续等待)或者会重发rwnd=x。
慢开始算法是指开始发送数据时,并不清楚网络的负荷情况,会先发送一个1字节的试探报文,当收到确认后,就发送2个字节的报文,继而4个,8个以此指数类推。
需要注意的是,慢开始的“慢”并不是指拥塞窗口的增长速率慢,而是指在TCP开始发送报文时先设置拥塞窗口=1。
拥塞避免算法是让拥塞窗口缓慢地增大,即cwnd加1,而不是如慢开始算法一样加倍。
根据上图的实例进行分析,一开始的慢开始算法的指数增长是很恐怖的,所以为了防止拥塞窗口cwnd增长过快需要设置一个门限ssthresh,这里是16。
(1)当 cwnd < ssthresh 时,使用上述的慢开始算法。
(2)当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
(3)当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。(通常做法)
无论在慢开始阶段还是在拥塞避免阶段,只要发送方没有收到确认,就认为这时候拥塞了,就要把慢开始门限ssthresh设置为此时发送方窗口值的一半(上例中是把发送方窗口值24修改为12)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。
这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
在慢开始和拥塞避免算法中,使用了“乘法减小”和“加法增大”方法。
其中”乘法减小“是指不论在慢开始还是拥塞避免阶段,只要出现一次超时(很有可能出现了拥塞),就把慢启动的初始阈值调整为当前拥塞窗口的一半值。当网络中频繁出现拥塞时,初始阈值就会下降的很快。以大大减少注入网络中的分组数。
”加法增大“是指在执行拥塞避免算法后,在收到对所有报文段的确认后(即经过一个RTT),就把拥塞窗口cwnd增加一个MSS大小,使得拥塞窗口缓慢增大,以避免网络的过早出现拥塞。
快重传是指,如果发送端接收到3个以上的重复ACK,不需要等到重传定时器溢出就重新传递,所以叫做快速重传,而快速重传以后,因为走的不是慢启动而是拥塞避免算法,所以这又叫做快速恢复算法。
如果没有快速重传和快速恢复,TCP将会使用定时器来要求传输暂停。在暂停这段时间内,没有新的数据包被发送。所以快速重传和快速恢复旨在快速恢复丢失的数据包。
快重传图解
快恢复是配合快重传的:
有以下两个要点:
①当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。
②考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。