1. 传输层的功能
从通信和信息处理的角度看,传输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。传输层位于网络层之上,它为运行在不同主机上的进程之间提供了逻辑通信,而网络层提供主机之间的逻辑通信。显然,即使网络层协议不可靠(网络层协议使分组丢失、混乱或重复),传输层同样能为应用程序提供可靠的服务。
传输层的功能如下:
1) 传输层提供应用进程之间的逻辑通信(即端到端的通信)。与网络层的区别是,网络层提供的是主机之间的逻辑通信。从网络层来说,通信的双方是两台主机, IP 数据报的首部给出了这两台主机的IP 地址。但“两台主机之间的通信”实际上是两台主机中的应用进程之间的通信,应用进程之间的通信又称端到端的逻辑通信。
2) 复用和分用。复用是指发送方不同的应用进程都可使用同一个传输层协议传送数据;分用是指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程。
3) 传输层还要对收到的报文进行差错检测(首部和数据部分)。而网络层只检查IP 数据报的首部,不检验数据部分是否出错。
4) 提供两种不同的传输协议,即面向连接的TCP 和无连接的UDP 。而网络层无法同时实现两种协议(即在网络层要么只提供面向连接的服务,如虚电路;要么只提供无连接服务,如数据报,而不可能在网络层同时存在这两种方式)。
2. UDP协议
RFC 768 定义的UDP 只是做了传输协议能够做的最少工作,它仅在IP 的数据报服务之上增加了两个最基本的服务:复用和分用以及差错检测。如果应用程序开发者选择UDP 而非TCP,那么应用程序几乎直接与IP 打交道。
为什么应用开发人员宁愿在UDP 之上构建应用,也不选TCP?
既然TCP提供可靠的服务,而UDP 不提供,那么TCP 总是首选吗?答案是否定的,因为有很多应用更适合用UDP,主要是因为UDP 具有如下优点:
1) UDP 无须建立连接。因此UDP 不会引入建立连接的时延。试想如果DNS 运行在TCP 而非UDP上,那么DNS 的速度会慢很多。HTTP 使用TCP 而非UDP, 是因为对于基于文本数据的Web网页来说可靠性是至关重要的。
2) 无连接状态。TCP 需要在端系统中维护连接状态。此连接状态包括接收和发送缓存、拥塞控制参数和序号与确认号的参数。而UDP 不维护连接状态,也不跟踪这些参数。因此,某些专用应用服务器使用UDP 时,一般都能支持更多的活动客户机
3) 分组首部开销小。TCP 有20B 的首部升销,而UDP 仅有8B 的升销。
4) 应用层能更好地控制要发送的数据和发送时间。UDP 没有拥塞控制,因此网络中的拥塞不会影响主机的发送效率。某些实时应用要求以稳定的速度发送,能容忍一些数据的丢失,但不允许有较大的时延,而UDP 正好满足这些应用的需求。UDP 常用于一次性传输较少数据的网络应用如DNS 、SNMP 等,因为对千这此应用,若采用TCP, 则将为连接创建、维护和拆除带来不小的开销。UDP 也常用于多媒体应用(如IP 电话、实时视频会议、流媒体等),显然,可靠数据传输对这些应用来说并不是最重要的,但TCP的拥塞控制会导致数据出现较大的延迟,这是它们不可容忍的。
UDP 提供尽最大努力的交付,即不保证可靠交付,但这并不意味着应用对数据的要求是不可靠的,因此所有维护传输可靠性的工作需要用户在应用层来完成。应用实体可以根据应用的需求来灵活设计自己的可靠性机制。
3. TCP协议
TCP 是在不可靠的IP 层之上实现的可靠的数据传输协议,它主要解决传输的可靠、有序、无丢失和不重复问题。TCP 是TCP/IP 体系中非常复杂的一个协议,主要特点如下:
1) TCP 是面向连接的传输层协议。
2) 每条TCP 连接只能有两个端点,每条TCP 连接只能是点对点的(一对一)。
3) TCP 提供可靠的交付服务,保证传送的数据无差错、不丢失、不重复且有序。
4) TCP 提供全双工通信,允许通信双方的应用进程在任何时候都能发送数据,为此TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。发送缓存用来暂时存放以下数据:(1)发送应用程序传送给发送方TCP 准备发送的数据;(2)TCP 已发送但尚未收到确认的数据。接收缓存用来暂时存放以下数据:(1)按序到达但尚未被接收应用程序收取的数据;(2)不按序到达的数据。
TCP连接的建立
在TCP 连接建立的过程中,要解决以下三个问题:
1) 要使每一方都能够确知对方的存在。
2) 要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项、时间戳选项及服务质量等)。
3) 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
三次握手建立连接
第一步:客户机的TCP 首先向服务器的TCP 发送一个连接请求报文段。这个特殊的报文段中不含应用层数据,其首部中的SYN标志位被置为1 。另外,客户机会随机选择一个起始序号seq =x(连接请求报文不携带数据,但要消耗一个序号)。
第二步:服务器的TCP 收到连接请求报文段后,如同意建立连接,就向客户机发回确认,并为该TCP 连接分配TCP 缓存和变量。在确认报文段中, SYN 和ACK 位都被置为1, 确认号字段的值为x+ 1, 并且服务器随机产生起始序号seq= y( 确认报文不携带数据,但也要消耗一个序号)。确认报文段同样不包含应用层数据。
第三步:当客户机收到确认报文段后,还要向服务器给出确认,并且也要给该连接分配缓存和变量。这个报文段的ACK 标志位被置1, 序号字段为x+ 1, 确认号字段ack=y+ 1 。该报文段可以携带数据,若不携带数据则不消耗序号。成功进行以上三步后,就建立了TCP 连接,接下来就可以传送应用层数据。TCP 提供的是全双工通信,因此通信双方的应用进程在任何时候都能发送数据。另外,值得注意的是,服务器端的资源是在完成第二次握手时分配的,而客户端的资源是在完成第三次握手时分配的,这就使得服务器易于受到SYN 洪泛攻击。
四次握手释放连接第一步:客户机打算关闭连接时,向其TCP 发送一个连接释放报文段,并停止发送数据,主动关闭TCP 连接,该报文段的FIN 标志位被置1, seq= u, 它等于前面已传送过的数据的最后一个字节的序号加1 (FIN 报文段即使不携带数据,也要消耗一个序号)。TCP 是全双工的,即可以想象为一条TCP 连接上有两条数据通路。发送FIN 报文时,发送FIN 的一端不能再发送数据,即关闭了其中一条数据通路,但对方还可以发送数据。
第二步:服务器收到连接释放报文段后即发出确认,确认号是ack = u + 1, 而这个报文段自己的序号是V, 等于它前面已传送过的数据的最后一个字节的序号加1 。此时,从客户机到服务器这个方向的连接就释放了, TCP 连接处于半关闭状态。但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭。
第三步:若服务器已经没有要向客户机发送的数据,就通知TCP 释放连接,此时其发出FIN= 1 的连接释放报文段。
第四步:客户机收到连接释放报文段后,必须发出确认。在确认报文段中, ACK 字段被置为1, 确认号ack= w + 1, 序号seq= u + 1 。此时TCP 连接还未释放,必须经过时间等待计时器设置的时间2MSL 后, A 才进入连接关闭状态。
对上述TCP 连接建立和释放的总结如下:1) 连接建立。分为3 步:
1、SYN = 1, seq = x
2、SYN= 1, ACK= 1, seq= y, ack = x + 1
3、ACK= 1, seq= x + 1, ack = y + l
2) 释放连接。分为4 步:
1、FIN= 1, seq =u
2、ACK = 1, seq = v, ack = u + 1
3、FIN= 1, ACK= 1, seq= w, ack = u + 1
4、ACK= 1, seq= u + 1, ack = w + 1