传输层时向上层的应用层提供通讯服务的,是属于面向通信部份的最高层,同时也是用户功能的最底层
传输层有两个很重要的特点:复用、分用
复用:应用层所有的应用进程都可以通过运输层再传到网络层
分用:运输层从网络层收到发送给各个应用进程的数据后,必须分别交付到指明的各个应用进程。
传输层提供应用进程间的逻辑通信。看上去这中通信时水平方向直接传输数据,但是实际上这两个运输层之间没有水平方向的木李连杰。
与网络层之间的区别:
网络层是为主机之间的通信提供服务,而传输层则是在网络层的基础上,唯一用进程之间的通信提供服务、
运输层向高层用户屏蔽了下面网络和信息姐,它使进程看见的好像再两个运输层实体之间有一条端到端的通信道路,但实际上逻辑通信信道对上层的表现因运输层使用的不同协议有很大的区别。
此外,运输层还应当有试错检测。
TCP协议(传输控制协议):体统面向连接的服务,在传输数据的时候必须先建立连接,数据传输结束后还要释放连接。TCP不提供广播和多播服务。尽管下面的网络是不可靠的,TCP也要尽可能提供一条双工可靠的通信信道。TCP要提供可靠的、面向连接的运输服务,因此不可避免的增加开销,例如确认、流量统计、计数器以及连接管理等
UDP(用户数据报协议)::UDP传输数据时不需要先建立连接,远程主机的运输层收到UDP的报文后,不需要给出任何确认。虽然UDP不提供可靠的交付,但是由于UDP非常简单,在某种情况下是一种最有效的工作方式。例如DNS服务就需要UDP
软件端口是应用层的各种协议进程与传输实体进行交互的地点。
端口号指具有本地意义,他只是为了表基本计算机应用层中的各个进程再和运输层交互时的层间接口,在互联网中不同的计算机相同的端口。是没有实际意义的.15位端口号允许有65535个不同的端口
分类:
UDP再IP的数据报服务上加入了很少一点功能:复用、分用、差错检测功能。
用户数据包UDP = 数据字段+首部字段
首部字段仅有8个字节,由4个字段组成,每个字段的长度都是2字节
TCP时TCP/IP中非常复杂的一个协议
TCP报文段的前20字节是固定的,后面有4n字节是根据需要而增加的。因此TCP首部的最小长度是20字节
各占两个字节,分别写入元端口号和目的端口号,与UDP的分用相似。
占4个字节,
序号范围是0~2^32 -1,序号增加到2^32 -1后,下一个序号又会回到0,也就是说序号使用了mod 2^32运算。
在一个TCP连接中传送的字节流中的每一个字节都按顺序编号,首部中的序号字段值指的是本报文段所发出的数据的第一个字节的序号
这个字段也被称为报文段字段
占用4个字节
是期望收到对方下一个报文段的第一个数据字节的序号。
若确认号位N,则表明到序号N-1位置所有的数据都已经正确收到了
占4位
他指出TCP报文段的数据起始位置距离TCP报文段的起始位置的距离。实际上就是指出TCP报文段的首部长度
4位二进制表示的最大的十进制数字是15,因此数据偏移量的最大值为60字节,这是TCP首部的最大长度,(选项的长度不能超过40字节)
占6为,保留位今后使用,但目前应为0
当URG=1,表明紧急指针阻断有序。告诉该系统此报文中有紧急数据,应该尽快传送。就不再按照原来的排队顺序传送,而是把它查到本报文段数据的最前面,但是紧急数据也是普通数据,需要配合紧急指针字段使用
当ACK=1时确认号字段有效,当ACK=0时,确认号无效
当两个应用进程进行交互式的通信时,又是在一段的应用程序希望能够快速的收到对方的相应,在这种情况下,会将PSH设置为1,这时候就不会在等待缓存填满再向上交付,而是直接交付。
表名出现了严重的差错,必须释放连接,然后重新建立连接
再连接建立时用来同步序号
当SYN = 1而ACK = 0时,表示这是一个连接请求报文段,若同意建立连接,则将响应中的ACK=1、SYN=1.
所以SYN置为1表示这是一个连接请求或者连接接收报文
用来释放一个连接。当FIN=1时,表示此报文段发送的数据已经发送完毕,要求释放运输链接
占两个字节
窗口之时0~2^16 -1之间的整数,窗口之的是发送本报文段的一方的接收窗口(不是自己的)。窗口之告诉对方:从本报文段首部中的确认号算起,接受放目前允许对方发送的数据量。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之:窗口值作为接收方让发送方设置其发送窗口的依据
窗口字段明确指出了允许对方发送的数据量。窗口值经常在动态的变化
内部有MSS(数据字段的最大长度)、选择确认、时间戳
TCP把连接作为最近本的抽象,TCP的许多特性都与TCP面向连接这个基本特征有关。
套接字(socket):IP:端口号
每一条TCP连接唯一的被通信两端的两个断电所确定,即
TCP连接::={socket1,socket2}={(IP1:port1),(IP2:port2)}
停止等待就是没法送完一个分组就停止发送,等待对方的确认,在收到确认后在发送下一个分组
M1发送过去后收到M1的确认回复,就继续发送M2
如果M1没有接收到数据或者M1发现验证完数据有误选择丢弃报文后不会进行任何操作,A超过一定时间没有接收到确认就认为之前的分组丢失了,就会重新发送之前的分组。这个过程就叫做超时重传。实现超时重传,就依赖于一个超时计时器。如果超时计时器收到了对方的确认,就撤销已经设置的超时计时器。
需要注意的三点:
发送方在设定超时重传的时间内收到确认,并不知道自己发送的分组出现了什么原因,这时候就需要重新传输,接收方收到了重复的分组,就会采取两种措施:
上述这种可靠传输协议常称为自动重传请求ARQ。意思是重传请求时自动进行的。
ARQ是TCP的精髓所在,主要采用的是滑动窗口协议,这种协议比较复杂。
其实就是发送方维护一个发送窗口,只要是位于这个窗口内的分组连续发送出去,不需要对方确认,而接受方一般都是采用了积累确认的方式。接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,安排需到达的最后一个分组发送确认。
优点: 容易实现,即使确认丢失也不必重传
缺点:不能像发送方及时反映接收方已经正确收到的所有分组
TCP流量控制就是让发送方的发送频率不要太快,要让接收方来得及接受
发送方的窗口不能超过接收方给出的接收窗口的数值。【TCP的窗口单位是字节,不是报文段】
此外还会存在一个僵局:
当接收方向发送方发送了零窗口的报文之后,过了一段时间有存在了一些缓存,于是接收方向发送方发送了一个rwnd(接收窗口)=400的保温段,但是再传输过程中丢失了,那么接收方就会一直发送,发送方一直等待,为了解决这个僵局采用了持续计时器
TCP为每一个连接都设置了一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就会发送一个零窗口探测报文段(仅携带1字节的数据),而对方再确认这个探测报文段时给出了现在的窗口值。如果窗口仍未0,就重新设置持续计时器。如果不为0,就返回了新的窗口值,打破了僵局
TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1字节(这样子会使接收缓存腾出来1字节),然后像发送方发送确认,并把窗口设置为1字节,但是发送放的报文段首部至少40字节,接着发送方发来了一字节的数据(41字节),接收方发送确认,仍将窗口设置为1字节。这样子进行下去,会使网络的效率很低
可以让接收方等待一段时间,使得或者接收缓存已有足够的空间容纳一个最长的报文段,或者等待接收缓存已有一半空闲空间。
此外,发送方也可以不发送太小的报文段,而是把数据积累成足够大的报文段,或者达到接收方缓存的空间的一半大小
也可以配合使用: 发送方不发送很小的报文段的同时,接收方也不要再缓存刚有一小点的空间就急忙把这个很小的窗口大小信息通知给发送方
拥塞? 拥塞指的是网络中对某一字段的需求超过了该资源所能提供的可用部分,使得网络的性能变差
拥塞往往是很多因素引起的且常常趋于恶化,拥塞控制与流量控制密不可分。
拥塞控制就是防止过多的数据注入到网络中,这样可以是网络中的路由器或者链路不至于过载。拥塞控制的所做的都有一个前提:网络能够承载现有的网络符合。这是一个全局性的过程,涉及到所有主机、路由器以及与降低网络传输性能的有关的所有因素。
当网络的吞吐量明显小于理想的吞吐量就会进入到轻度阻塞,但是网络的吞吐量持续下降,这时候就会进入一个拥塞状态,当达到0时,网络已经无法工作,这时候就成了所谓的死锁。
拥塞控制非常难设计,因为它是一个动态的问题,而不是静态的。目前存在两种方式:开环控制、闭环控制
开环控制就是在设计网络的时候就把所有的情况都考虑到,力求网络在工作时不产生拥塞,但一旦整个系统运行起来,就无法再进行改正。
闭环控制是基于反馈环路的概念,主要措施:
1. 检测网络系统以便于检测到何时、何处发生
1. 把用色发生的信息传送到可采取行动的地方
1. 调整网络系统的运行已解决出现的问题
控制算法:慢开始、拥塞避免、快重传、快恢复,这几种算法也是基于窗口的拥塞控制
当主机再已建立的TCP连接上开始发送数据时,并不清楚当前网络的负荷状态,。如果立即把大量的数据字节注入到网络中,那么就有可能引起网络阻塞。一般来说先进行探测,即由小到大逐渐增大注入到网络中的数据字节,也就是说,由小到达逐渐增大拥塞窗口的数值
一般来讲设置初始的cwnd(拥塞窗口)的值为1或者2,每次确认成功就乘2(重传确认不进行该操作)。为了防止拥塞窗口增长的过大引起网络阻塞,还需要设置一个慢开始门限(ssthresh)状态变量,可以设置的大一些,比如说发送窗口的最大容许两
基础如下:
cwnd< ssthreash :使用慢增长
cwnd > ssthrash: 使用拥塞避免算法
cwnd == ssthrash: 慢开始和拥塞避免算法都可以使用
目的是为了让拥塞窗口缓慢增长,使拥塞窗口不再是像开始那样加倍增长,而是进行加法进行增大,这个过程就是加法增大。使得拥塞窗口线性缓慢增大
如果cwnd增长到一定值之后网络出现了超时,这是网络发生阻塞的标志,这时候需要调整门限值:ssthresh=cwnd/2,然后cwnd重置,再重新进行之前的流程。
个别报文可能会丢失,而不是发生了网络拥塞,这可能使发送方认为网络发生了拥塞,错误的开启了慢开始。使得cwnd有设置了1,不必要的降低了传输效率
快重传算法可以让发送方尽早地知道发生了个别报文段丢失。快重传首先要求接收方不要等待自己发送数据时才稍带确认,而是立即发送确认,及时收到了失序的报文段,也要立即发送对已收到的报文段的重复确认。
比如书评M3丢失了,收到了M4、M5、M6、M7,这时候会发送重复确认,都进行确认M2,接收方只要一连收到了3个重复的确认就知道当前没有发生网络阻塞,知识发生了丢失,这时候再次重传少收到的报文段(M3)即可
发送方在收到一连串3个重复确认后,知道使丢失了个别的报文段,先不启动慢启动而是进行快恢复:
在刚开始的时候,客户端B的TCP服务器进程会先创建一个传输控制快TCB(内部存储一些重要信息,比如说TCP连接表、只想发送和接收缓存的指针、指向重传队列的指针、当前发送和接受的序号等等),然后服务器处于LISTEN(收听)状态,等待客户端的连接请求。
客户端A的TCP进程也先创建传输控制块TCB,然后在建立TCP连接时,向服务器B发送请求报文段,这时候首部的同步位SYN=1,同时选择一个初始序列号seq=x。TCP规定SYN报文段不能携带数据,但是要消耗一个序号,这时候客户进程进入到SYN-SENT(同步已发送状态)
服务端B收到请求报文段后,如果同意连接,则向A发送确认,确认报文中应把SYN和ACK的位置都设置位1,确认学列号ACK= X(客户A生成的初始序列号)+1,同时自己也声称一个初始序号seq = y,这个报文段也不能携带数据,但是要消耗一个序号。这时候TCP服务B进程至于SYN-REVD(同步收到)状态。
TCP客户进程收到B的确认后,同样需要对B给出确认,确认报文段的ACK置为1,确认号位ack = y(TCP服务端的序号)+1;TCP规定ACK报文是可以携带数据的,但是如果不携带数据则不消耗序列号。这种情况下下一个数据的报文段序列号仍是seq=x+1 或者说等于B服务发送来数据报的ack(确认号)。在这时TCP连接已经建立,A进入到了ESTABLISHED(已建立连接)状态。
B在收到A的确认之后也会进入ESTABLISHED(已建立连接)状态
上述的过程就是三次握手
所谓的四次握手只不过是再服务端TCP向客户端TCP发送的数据进行了拆分,再之前为把ACK和SYN(等于1的时候不携带数据)都置为1,然后自己在生成一个序号。而四次挥手是把这个过程拆成了两部分:
这两中效果时一样的
进行两次握手无非是在三次握手的基础上,省略了最后一次握手(进行确认)
最后一次确认主要是为了防止已失效的连接请求报文段忽然传到了服务端,,从而产生错误。
已失效的连接请求报文段: 客户端发送了报文因为网络拥塞没有让服务端B接收到,由于自动重发机制,客户端A就再次进行了重发了一个新的请求。但是旧的请求比新的请求先打到服务端B,就误认为这就是A的一次请求,于是就像A发送了确认报文段,同意建立连接。这时候客户端B以为已经建立了新的运输连接,一直等待A发送数据,这样会导致数据的白白浪费
无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
三次握手在服务端收到建立连接请求后会像客户端发送一个应答,这时候客户端就会对此进行一个检测,如果这个ACK不是最新的ACK,就会发送RST数据报文段,结束这段连接。
三次即可完成,进行四次握手,不过是资源的浪费
【1】数据传输结束后,通信的双方都可以释放连接,现在A和B都处于ESTABLISHED状态(已建立连接状态)。A(客户端)的应用进程先向其TCP发出连接释放报文段,并停止在发送数据。主动关闭TCP连接。A把连接释放的报文段首部的终止控制位FIN置为1,其序号seq=u,它等于前面已传送过的的数据的最后一个字节的序号加一。这时候A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。TCP规定,FIN报文段即使不带数据也需要消耗一个序号
【2】B收到连接释放报文段后即发出确认,确认号是ack+1,而这个报文段自己的序号是v,等于B前面已传送过去的数据的最后一个字节的序号加一。然后B就进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接已经释放了,这时候TCP连接处于版关闭状态,即A已经没有数据要发送了,但是B若发送数据,那么A仍要接受,也就是说B到A这个方向的连接未关闭,这个状态会持续一段时间。
【3】A收到了来自B的确认后就会进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
若B已经没有要想A发送的数据,其应用进程就通知TCP释放连接,这是B发出的连接释放报文段必须使FIN=1,假定B的序号为w(版关闭状态B可能有发送了一些数据),B还必须重复上次已经发送过的确认号ack=u+1,这是B进入LAST-ACK(最后确认状态),等待A的确认
【4】A收到B的连接释放报文段后,必须对此发出确认。在确认文段中ACK置为1,确认号ack=w+1,而自己的序号是seq=u+1,然后进入到TIME-WAIT(时间等待)状态。现在TCP连接还没有释放掉,必须等待时间等待计时器设置的时间2MSL(最长报文段寿命)后,A才会进入到CLOSED状态。
为什么要设置2MSL
首先,是为了保证A发送的最后一个ACK报文段能够到达B,这个ACK报文段有可能丢失,因为LAST-ACK状态的B收不到对以发送的FIN+ACK报文段的确认,B会超时重传这个FIN+ACK报文段。而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后A和B都正常进入到CLOSED状态。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段就直接释放连接。无法接收到B的FIN+ACK报文段,因为也不会再发送一次确认报文段。导致B无法正常进入到CLOSED
其次是为了防止已失效的链接请求报文段出现在本连接中。A在发送完最后一个ACK报文段后,在经过2MSL,就可以是本连接持续时间内的所有报文段都从网络上消失
如果客户端的主机忽然出现故障,服务端无法收到客户端发送来的请求。服务器没收到一次客户端发送来的数据,就hi重新设置以下保活计时器,时间的设置通常是2小时。若长时间没有收到数据,服务器就会发送一个探测报文段,以后每个75s发送一次,若一连发送了10个探测报文段然然没有客户相应,服务器就认为这个客户端出现了故障,然后就关闭这个连接