参考书:谢希仁《计算机网络(第7版)》、王道计网课程、天勤计网课程等。
(1)传输层为应用层提供通信服务,使用网络层的服务。
(2)传输层的功能:
(3)网络层提供主机之间的逻辑通信。只有主机才有层次。
(1)传输层有两个好兄弟,大哥TCP和小弟UDP,大哥靠谱,小弟不靠谱。
(2)TCP
(3)UDP
(1)复用:应用层所有的应用进程都可以通过传输层再传输到网络层。
(2)分用:传输层从网络层收到数据后,交付到指明的应用进程。
(3)端口
(4)端口号主要运用于传输层上,用来标识同一台计算机中进行通信的不同应用程序(进程)。因此也被成为应用程序地址。
(5)端口号只有本地意义,在因特网中不同计算机的相同端口是没有联系的。也就是说,不同计算机中,相同端口号可以指代不同的进程。
(6)端口号长度为16bit ,能表示65536个不同的端口号。
(7)端口号(按范围分):
(8)套接字
在网络中采用发送方和接收方的套接字组合来识别端点,套接字唯一标识了网络中的一个主机和它上面的一个进程。
(1)UDP只在IP数据报服务之上增加了很少功能,即复用分用和差错检测功能。
(2)UDP的主要特点:
(3)应用层给UDP多长的报文,UDP就照样发送,即一次发一个完整报文。
分用时,找不到对应的目的端口号,就丢弃报文,并给发送方发送ICMP"端口不可达"差错报告报文。
UDP长度:UDP首部(8B)+ 数据部分长度(不包括伪首部)。
在发送端:
伪首部 + 首部 + 数据部分 采用二进制反码求和
在接收端:
(1)序号:在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,本字段表示本报文段所发送数据的第一个字节的序号。
(2)确认号:期望收到对方下一个报文段的第一个数据字节的序号。若确认号为N,则证明到序号N-1为止的所有数据都已正确收到。
(3)数据偏移(首部长度):TCP报文段的数据起始处 离 TCP报文段的起始处 有多远,以4B为单位,即1个数值是4B。
(4)6个控制位(注意点)
紧急位URG:URG = 1时,表明此报文段中有紧急数据,是高优先级的数据,应尽快传送,不用在缓存里排队,配合紧急指针字段使用。
确认位ACK:ACK = 1时确认号有效,在连接建立后所有传送的报文段都必须把ACK置为1。
推送位PSH:PSH = 1时,接收方尽快交付接收应用进程,不再等到缓存填满再向上交付。
复位RST:RST = 1时,表明TCP连接中出现严重差错,必须释放连接,然后再重新建立传输链接。
同步位SYN:SYN = 1时,表明是一个连接请求/连接接收报文。
终止位FIN:FIN = 1时,表明此报文段发送方数据已发完,要求释放连接。
(7)窗口:指的是发送本报文段的一方的接收窗口,即现在允许对方发送的数据量。
(8)校验和:检验首部 + 数据,检验时要加上12B伪首部,第四个字段为6。
(9)紧急指针:URG = 1时才有意义,指出本报文段中紧急数据的字节数。
(10)选项:最大报文段长度MSS、窗口扩大、时间戳、选择确认等。
MSS:MSS的全称为Maximum segment size,双方协商的每一个报文段所能承载的最大数据长度(不包括文段头)。
WS:WS的全称为Window scale,即窗口规模(因子)。它是用来调整窗口大小的。前面我们说到过窗口大小的字段,那这个窗口因子又是做什么用的呢?早期的网络带宽、硬件配置都比较差,所以窗口大小最大只预留了16个bit,也就是最大能设置的值为65535。随着硬件和网络的发展,65535已经不能满足。所以就增加了一个WS的选项来扩展!如果设置了WS,那实际的窗口大小就等于窗口大小乘以窗口因子。
SACK:SACK的全称为Selective ACK,即选择性确认。它是建立在累计确认(后面讲) 的基础上的!只有收到失序的分组时才会可能会发送SACK,如果接收方接收到了后面的数据包,而发现前面的数据包丢失,则会通知发送方哪些报文段丢失,需要重发!
(11)填充:这个字段是为了让整个头部为4个字节的倍数。
(1)传输层:使用TCP实现可靠传输。
(2)网络层:提供尽最大努力交付,不可靠传输。
1. 可靠:保证接收方进程从缓冲区读出的字节流与发送方发出的字节流是完全一样的。
2. TCP实现可靠传输的机制:(1)校验、(2)序号、(3)确认、(4)重传
(1.1)校验:与UDP校验一样,增加伪首部。
(2.1)序号:一个字节占一个序号,序号字段指的是一个报文段第一个字节的序号。
(3)确认重传不分家,TCP的发送方在规定的时间(重传时间)内没有收到确认,就要重传已发送的报文段。 即超时重传。
(4)TCP采用自适应算法,动态改变重传时间RTTs(加权平均往返时延)。还是等太久了!!
(5)冗余ACK(冗余确认)来解决: 建议看看老谢的可靠传输过程图!
每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号。
发送方已发送1,2,3,4,5报文段。
接收方收到1,返回给1的确认(确认号为2的第一个字节)。
接收方收到3,返回给1的确认(确认号为2的第一个字节)。
接收方收到4,返回给1的确认(确认号为2的第一个字节)。
接收方收到5,返回给1的确认(确认号为2的第一个字节)。
发送方收到3个对于报文段1的冗余ACK——> 认为2报文段丢失,重传2号报文段 即快速重传。
TCP连接的建立采用 客户服务器方式(C/S方式),主动发起连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫服务器。涉及IT界常说的"三次握手、四次挥手"。
三次握手,四次挥手(快记)
# 三次握手
最少需要3次,保证稳定连接!
A:我们能交流一下吗?
B:可以~
A:开聊~
# 四次挥手
C:我要走了
D:我知道你要走了
D:你真的要走了吗?(确定C真的走了)
C:我真的要走了!
假设运行在一台主机(客户)上的一个进程想与另一台主机(服务器)上的一个进程建立一条连接,客户应用进程首先通知客户TCP,他想建立一个与服务器上某个进程之间的连接,客户中的TCP会用以下步骤与服务器中的TCP建立一条TCP连接:
Round 1:客户端发送连接请求报文段,无应用层数据。
SYN = 1,seq = x (随机)
Round 2:服务器端为该TCP连接分配缓存和变量,并向客户端返回确认报文段,允许连接,无应用层数据。
SYN = 1,ACK = 1,seq = y (随机),ack = x+1
Ruond 3:客户端为该TCP连接分配缓存和变量,并向服务器端返回确认的确认,可以携带数据。
SYN = 0,ACK = 1,seq = x+1,ack = y+1
参与一条TCP连接的两个进程中的任何一个都能终止连接,连接结束,主机中的"资源"(缓存和变量)将被释放:
Round 1:客户端发送连接释放报文段,停止发送数据,主动关闭TCP连接。
FIN = 1,seq = u
Round 2:服务器端回送一个确认报文段,客户到服务器这个方向的连接就释放了——半关闭状态。
ACK = 1,seq = v,ack = u+1
Round 3:服务器端发完数据,就发出连接释放报文段,主动关闭TCP连接。
FIN = 1,ACK = 1,seq = w,ack = u+1
Round 4:客户端回送一个确认报文段,再等到时间等待计时器设置的2MSL(最长报文段寿命)后,连接彻底关闭。
ACK = 1,seq = u+1,ack = w+1
(1)通信协议的简单概念
协议:约定,就好比我们所说的是用普通话对话,不然我听不懂你说的是什么“鸟语”。
网络通信协议:速率、传输码率、代码结构、传输控制……
问题:非常复杂?
大事化小:分层!
TCP/IP协议簇:实际上是一组协议。
重要的协议:
TCP:用户传输协议。
UDP:用户数据报协议。
出名的协议:
TCP:用户传输协议。
IP:网际互连协议。
(2)TCP 对比 UDP:
TCP:如打电话。
连接、稳定。
客户端、服务端 分明。
三次握手,四次挥手。
传输完成,释放连接,效率低。
UDP:如发短信。
不连接,不稳定。
客户端、服务端 没有明确的界限。
不管有没有准备好,都可以发给你。
(3)SYN洪泛攻击
SYN洪泛攻击发生在传输层,这种方式利用TCP协议的特性,就是三次握手
。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行确认,那么这个TCP连接处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。处理方式:SYN cookie。
(1)保证传输的可靠我们前面已经说到了面向连接,建立连接是保证数据传输的第一步。那在连接建立之后的数据传输怎么保证可靠呢?
(2)我们再次回到我们打电话的场景,一般在对话的过程中,都是得双方都有互动,给与对方回应。而不是一个人一个劲的说而另一方没有任何回应!比如下面场景:
A:跟你讲哦,我上周图书馆认识了一个很好看的帅哥!
B:哟,不得辽,牛逼啊!
A:然后我昨天约出来见面了!嘻嘻!
B:666!然后呢?
A:然后,巴拉巴拉……
B:卧槽,你刚刚说啥我没听清,你再说一遍?…
(3)这样的确认和应答就确保了双方的通信能够完整可靠。TCP也采用了这种y应答和确认重传的机制,保证在不可靠的网络上实现可靠的传输。只要我没有收到确认,我就认为没有发送成功,就会重发。
停止等待协议就是每次给对方发送数据包后,需要等待对方的回应然后再发送下一个数据包!停止等待协议会出现如下几种情况:
1、无差错情况:A发送M1包到B,B收到后会给A一个确认,当A收到B的确认后再发送包M2。
2、超时重传:A发送M1包到B,如果发送过程中包丢失,A会重新发送。A等待重发的时间是比一个报文的往返时间(RTT)稍微多一点。
3、确认丢失:如果B在给A发送确认的时候丢失,A会重新发送M1包给B,由于B已经处理过M1的数据包所以B会丢弃报文,然后重传确认M1给A。
4、确认迟到:如果A发送数据包M1给B,B回复确认的时候延迟了。这时A又会重新发送包M1给B,B收到后丢弃数据包,然后重传确认M1给A。这时A会收到多次确认,当第二次收到迟到的确认后A也会丢弃该确认。
从上面能看到,停止等待协议每次都是等到收到确认后再发下一个数据包。只要我没收到你给我的确认,我就认为你没有收到我发的数据包,我就会进行重发!这样虽然可靠,但是会导致信道利用率较低!
(1)流水线传输就是每次发送多组数据包,不必每次发完一组就停下来等待对方的确认。由于信道上一直有数据不间断的传输,因此可以获得较高的信道利用率!
(2)流水线传输如何保证可靠的呢?需要发送方维持发送窗口,假如发送窗口是5,那5个数据包会同时发送,然后等确认!如果有收到接收方的确认,窗口就会滑动,进行第6个数据包的发送。
(3)如果都是单个确认,可能效率会比较低,所以有了累计确认!也就是说假如发送方发送了数据包1、2、3、4,接收方只需要回复对数据包4的确认,那表示1234数据包都已经收到了,就可以进行第五个数据包的发送了!假如发送了数据包1、2、3、4,其中第三个数据包丢失,那该怎么确认呢?TCP只会回复对数据包2的确认,并且对数据包4进行选择性确认(TCP头部选项讲到过的SACK),这样发送方就知道数据包4已经成功发送,只需要重发数据包3。
继续前面抓包的例子,接收方并不是对每个数据包都进行确认,而是对多个数据包进行累计确认:
这里我们能看到服务器发送多个数据包后,客户端才进行了一次确认。
(1)通过前面我们知道了,通过建立可靠的连接和确认机制,保证了TCP的连接的可靠!但是每个人使用的计算机的处理能力都是不一样的,我发送太快了对方处理不过来怎么办呢?通信双方怎么去协调发送和接收数据的频率呢?因此,出现了流量控制和拥塞控制。
(2)举例:
A向B发送数据,连接建立时,B告诉A:“我的rwnd = 400(字节)”,设每一个报文段100B,报文段序号初始值为1。
探测报文段
。接收方收到探测报文段时给出现在的窗口值。若窗口仍然是0,那么发送方就重新设置持续计时器。(1)假设现在A需要传输数据给B,B就先要告诉A自己的接收窗口有多大。A根据B的接收窗口设置自己的发送窗口!A的发送窗口时不能大于B的接收窗口的!在开始传输数据之前,初始的窗口设置如下图:
(2)如上图我们能否看到,B的接收窗口设置为10个字节,那A的发送窗口设置不能超过10个字节!如果开始传送数据,A会将数据封装成多个数据包进行传输,如下图
(3)在没有收到B的确认之前,A的窗口不会滑动,也就是说最多能发10个字节的数据。如果B接受到数据且回复确认给了A,那A的窗口则进行滑动,如下图:
(4)这样,A又可以进行第11、12个字节的发送啦!如果B的处理能力变弱了,也可以通知A将发送窗口调小!这样也也就很好的协调了双方的接收和发送能力!这也就很好的实现了TCP的可靠传输和流量控制!
(5)上面的数据包继续发送,如果在发送过程中,3、4、5这三个字节组成的数据包丢了,但是后面的数据却收到了,这时候A的发送窗口会移动么?
(6)如果是这种情况,A的发送窗口是不会移动的。B在接收到后面数据包的时候回复给A的Ack会设置为3,且在选项中设置一个SACK(在TCP头部选项里面有描述),告诉A哪部分数据收到了,而哪部分数据需要进行重发!
(1)出现拥塞的条件:
对资源需求的总和 > 可用资源
1. 网络中有许多资源同时呈现供应不足 ——> 网络性能变坏 --> 网络吞吐量将随输入负荷量的增大而下降
2. 拥塞控制:防止过多的数据注入到网络中。【全局性】
(2)利用滑动窗口技术,可以很好的协调双方的收发能力。但是,网络状况是非常复杂的,且在同一个网络上可能有千千万万个发送方和接收方!如果大家都需要传输数据都需要占用网络,不做好控制措施,就会导致整个网络会堵塞甚至瘫痪。
(3)我们为了方便研究,通常使用如下假定:注意这个(3)可选择性地看!
(4)接收窗口 & 拥塞窗口:
1. 【接收窗口】:接收方根据接受而缓存设置的窗口值,并告知给发送方,反映接收方的容量。
2. 【拥塞窗口】:发送方根据自己估算的网络拥塞程度而设置的窗口值,反映网络的当前容量。
(5)拥塞控制生活化:
如果我要从深圳开车去广州,我就会走高速。如果只有我一个人开车,那肯定能畅通无阻!但是高速公路不是我家的,大家都能通行!所以一到了节假日,大家都蜂拥而上,而高速的承运能力不会因为节假日而调整!这时候往往就需要交通管制、限流等措施去舒缓交通!
1、绿线代表理想状况下,如果高速公路的吞吐量为100!当需要通过的车辆不超过100时,所有车辆都能顺利通过!当需要通过的车辆超过100,那每次通行的车辆为100,能提供的负载比较稳定。
2、红色代表没有任何交通管制情况下,如果高速公路的吞吐量为100!当需要通过的车辆不超过100时,会出现轻微的塞车现象!但是随着车辆的增多,就会出现严重的阻塞,甚至瘫痪!
3、蓝色代表在交通管制下,如果高速公路的吞吐量为100!当需要通过的车辆不超过100时,会出现轻微的塞车现象!但是随着车辆的增多,交通一直保存较高的负载,不会出现瘫痪的情况!
(1)发送方维持一个cwnd(拥塞窗口,注意这里的拥塞窗口不能大于前面说到的发送窗口!),刚开始拥塞窗口设置为1。如果发现这个包没有丢失,则调整拥塞窗口为2!如果又没有丢包,则调整拥塞窗口为4!这样每次以2倍的速度一直增长到16!然后17、18、19这样一个一个的增加,直到大小与发送窗口一致。这就是所谓的慢开始和拥塞避免,16就是慢开始门限…
(2)如果在发送的过程中发现有丢包现象,则会调整拥塞窗口大小为1,并且设置新的慢开始门限为出现拥塞时的二分之一,也就是说当拥塞窗口为24的时候出现丢包现象,那新的慢开始门限就调整为12!如果理解了上面的文字描述,下面的图就不难理解了!
(3)一个传输轮次:
(1)前面说过累计确认,还说到了选择性确认。这个就跟快重传有关!接收方如果发现丢包,不会等到累计确认,就通知发送方三个重复的确认通知对方重新发送丢失的包。当接收方收到三个重复的确认,则意识到数据包丢失,进行重传!
(2)通过下图能看到,当出现丢包的情况,接收方的Ack都是等于50,而SACK分别对60~89之间的字节都进行了选择性的确认!这时候发送方也就知道50~59这部分数据丢失而进行重传!
(3)如果一旦发生丢包,拥塞窗口就变成1,这种方式也太傻了吧。如果能有个快速恢复的机制就好了!TCP就使用了快恢复机制!当出现丢包时,不会再次进行慢开始,而是直接转入拥塞避免!也就是从新的慢开始门限进行加法增加!
(4)细品下图: