TCP/IP体系结构之传输层协议(TCP、UDP)

TCP/IP模型——传输层

  本篇文章,篇幅较长,全文大概18000多字,花费了近一周的时间才写完。写这篇文章的原因很简单:在面试中,总是会问到计算机网络方面的问题,而TCP是必不可少的。每一次的回答都不尽满意,甚至有些点自己还不清楚,所以自己决定将传输层协议这一块儿总结一下,相当于是一个再学习过程。如果你碰巧看到了这篇文章,又刚好对传输层协议感兴趣,那么不妨花费一点时间好好看一下,相信会对你有一定的帮助。

  若是你在浏览的过程中,发现文章有问题,请留言,我会尽快更正。谢谢。

  注:本篇文章是以谢希仁教授的《计算机网络》第七版为基础学习总结的。参考文献包括但不限于《计算机网络》、百度百科及CSDN等博文。

1. 传输层协议概述

1.1 进程间的通信

1.1.1 传输层的作用

  从通信和信息处理的角度看,传输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。当网络的边缘部分中的两台主机使用网络的核心部分的功能进行端到端的通信时,只有主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。

  传输层的任务:负责向两台主机中进程之间的通信提供通用的数据传输服务。

1.1.2 为什么需要传输层?

  从IP层来说,通信的两端是两台主机。IP协议能够把源主机A发送出的分组,按照首部中的目的地址,送交到目的主机B。但是,真正通信的实体不是主机,而是主机中的进程。所以,两台主机进行通信就是两台主机中的应用进程互相通信。IP协议只能将分组发送到目的主机,但是这个分组还停留在主机的网络层而没有交付给主机中的应用进程。从传输层的角度看,通信的真正端点是主机中的进程,端到端的通信是应用进程之间的通信。

1.1.3 复用和分用

  在一台主机中经常有多个应用进程同时分别和另一台主机中的多个应用进程进行通信。如图1,主机A的应用进程AP1和主机的AP3通信,而主机A中的AP2也和主机B中的AP4通信。这表明,传输层具有复用和分用的功能。

复用:发送方不同的应用进程都可以使用同一个传输层协议传送数据。

分用:接收方的运输层在去掉报文的首部后能够把这些数据正确交付目的应用进程。

图1:传输层为相互通信的应用进程提供了逻辑通信
传输层为相互通信的应用进程提供了逻辑通信

1.2 传输层协议

1.2.1 协议划分

传输层主要使用以下两种协议:

  • 用户数据报协议 UDP(User Datagram Protocol)——提供无连接的、尽最大努力的数据传输服务(不保证数据传输的可靠性),其传输的单位是用户数据报。
  • 传输控制协议 TCP(Transmission Control Protocol)——提供面向连接的、可靠的数据传输服务,其传输的单位是报文段。

UDP与TCP的区别:

  • UDP在传输数据之前不需要先建立连接。目的主机收到UDP报文后,不需要给出确认,UDP提供不可靠服务。有单播,广播,多播的功能。头部开销小,传输数据报文高效。
  • TCP提供面向连接的服务。传输数据之前必须先建立连接,数据传输结束后要释放连接。TCP不提供广播或多波服务。因为TCP提供可靠的、面向连接的运输服务,因此需要连接管理、确认、流量控制等。提供全双工通信,允许通信的双方应用程序在任何时候同时发送数据。

图2:使用 UDP和TCP协议的各种应用和应用层协议
使用 UDP和TCP协议的各种应用和应用层协议

1.2.2 协议端口号

协议端口号标识了一个主机上进行通信的不同的应用程序。

为什么需要端口号?

一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。因为IP 地址与网络服务的关系是一对多的关系,不能只靠IP地址来区分不同的服务。实际上是通过“IP地址+端口号”来区分不同的服务的。

  在TCP/IP协议,用源IP、源端口号、目的IP、目的端口号、协议号这样一个五元组来标识一个通信。

端口号划分:

  • 服务端使用的端口号:
  • 系统端口号:数值 0~1023。IANA把这些端口号指派给了TCP/IP最重要的一些应用程序,让所有用户知道并使用。
应用程序 FTP SSH TELNET SMTP DNS TFTP HTTP SNMP HTTPS
端口号 21 22 23 25 53 69 80 161 443
  • 登记端口号:数值为 1024~49151。这类端口号是没有被系统端口号的应用程序使用。使用这类端口号需要在IANA按照规定的手续等级,以防止重复。

  • 客户端使用的端口号:数值为 1024~49151。这类端口号在客户端进程运行时动态选择,也叫短暂端口号。这类端口号留给客户端进行选择暂时使用。当服务器进程收到客户进程的报文时,就知道客户进程使用的端口号,因而可以把数据发送给客户进程。通信结束后,刚才已经使用过的客户端口号就不存在,这个端口号可以供给其他客户进程使用。

两个问题

  1. 一个进程是否可以bind多个端口号?

    ​ 可以,因为一个进程可以打开多个文件描述符,而每个文件描述符对应一个端口号,所以一个进程可以绑定多个端口号。

  2. 一个端口号是否可以被多个进程bind?

    ​ 不可以,如果进程先绑定一个端口号,然后在fork一个子进程,这样的话就可以实现多个进程绑定一个端口号,但是两个不同的进程绑定同一个端口是不可以的。


2. 用户数据报协议 UDP

2.1 UDP 概述

  UDP提供无连接,尽最大努力交付的数据传输服务。

2.1.1 主要特点
  • UDP是无连接的,即发送数据不需要建立连接(发送数据结束也无需释放连接),因此减少了开销和发送数据之前的时延。
  • UDP使用尽最大努力交付,既不保证可靠交付,因此主机不需要维持复杂的连接状态表。
  • UDP是面向数据报文的。发送方的UDP对应用程序叫下来的报文,再添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不拆分,也不合并,而是保留这些报文的边界。
  • UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低。
  • UDP支持一对一、多对一、一对多和多对多的交互通信
  • UDP首部开销小,只有8个字节,比TCP的20个字节的首部要短。
  • UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作;UDP具有接收缓冲区,但这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃。

2.2 UDP首部格式

  用户数据报UDP有两个字段:数据字段和首部字段。如图3,各字段含义如下:

  • 源端口 源端口号。在需要对方回信时选用。不需要时可以全0。

  • 目的端口 目的端口号。终点交付报文时必须使用。

  • 长度 UDP用户数据报的长度,其最小值为8(仅有首部)

  • 检验和 检测UDP用户数据报在传输中是否有错。有错就丢弃。

图3:UDP用户数据报格式
UDP用户数据报格式
  当传输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口,上交最后的终点——应用进程。如果接收方UDP发现收到的报文中的目的端口号不正确,就丢弃该报文,并由网际控制报文协议ICMP发送“端口不可达”差错报文给发送方。


3. 传输控制协议 TCP

3.1 TCP 概述

  TCP提供一种面向连接的 、可靠的字节流服务。

3.1.1 主要特点
  • TCP是面向连接的传输层协议。应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
  • TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复,并且能按序到达。
  • TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端均设有发送缓存和接收缓存,用来临时存放双向通信的数据。
    • 在发送时,应用程序把数据传送给TCP的缓存后,就可以自己做自己的事,而TCP在合适的时候把数据发送出去。
    • 在接收时,TCP把收到的数据放入缓存,上层应用程序在合适的时候读取缓存中的数据。
  • 面向字节流。TCP中的“流”指的是流入到进程或从进程流出的字节序列。虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。
    • TCP不保证接收方的应用数据块和发送方所发出的数据块具有对应的大小关系(例如,发送方的应用程序给发送方的 TCP 10个数据块,接TCP的接收方可能只用了4个数据块就把收到的字节流交付上层的应用程序)。
    • TCP不关心应用进程一次把多长的报文发送到TCP缓存中,而是根据对方给出的窗口值和当前网络的拥塞程度来决定一个报文段应包含多少个字节。如果应用程序发送的数据块太长,TCP 会将其划分短一些在传送。如果应用程序一次只发一个字节,TCP收端也可以累积到足够多的字节发送给收端的应用程序。

图4:TCP面向字节流
TCP面向字节流

3.2 TCP 首部格式

  TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段。一个TCP报文段分为首部和数据两部分,而TCP的全部功能在首部的各个字段体现。

  TCP报文段首部前20个字节是固定的,后面有4n个字节是根据需要而增加的选项。因此TCP首部的最小长度是20个字节。

图5:TCP 报文段的首部格式
TCP报文段的首部格式
各字段意义如下:

  1. 源端口和目的端口:各占2 个字节, 分别写入源端口号和目的端口号。

  2. 序号:占4 字节。若序号达到最大,则下一个序号右回到0。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。首部中的序号字段值指的是本报文段所发送的数据的第一个字节的序号。

    ​ 例如, 一报文段的序号字段值是301, 而携带的数据共有100字节。这就表明: 本报文段的数据的第一个字节的序号是301, 最后一个字节的序号是400。显然, 下一个报文段(如果还有的话) 的数据序号应当从401 开始, 即下一个报文段的序号字段值应为401。这个字段的名称也叫做“ 报文段序号”。

  3. 确认号:占4个字节,是期望收到对方下一个报文段的第一个数据字节的序号。若确认号 = N,则表明:到序号N-1为止的所有数据都已经正确收到。

    ​ 例如, B 正确收到了A 发送过来的一个报文段,其序号字段值是501,而数据长度是200 字节(序号501 - 700),这表明B 正确收到了A 发送的到序号700 为止的数据。因此,B 期望收到A 的下一个数据序号701,于是B 在发送给A 的确认报文段中把确认号置为701。请注意,现在的确认号不是501,也不是700,而是701。

  4. 数据偏移:占4位,占4 位,它指出TCP 报文段的数据起始处距离TCP报文段的起始处有多远。这个字段实际上是指出TCP 报文段的首部长度。TCP 首部的最大长度为60个字节。

  5. 保留:占6 位,保留为今后使用,但目前应置为0。

  6. 标志位,各占1位。

    • 紧急URG:当URG=1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据, 应尽快传送(相当于高优先级的数据),而不要按原来的排队顺序来传送。当URG 置1时,发送应用进程就告诉发送方的TCP 有紧急数据要传送。于是发送方TCP 就把紧急数据插入到本报文段数据的最前面, 而在紧急数据后面的数据仍是普通数据。这时要与首部中紧急指针(Urgent Pointer)字段配合使用。
    • 确认ACK:仅当ACK= 1时确认号字段才有效。当ACK=0时,确认号无效。TCP 规定,在连接建立后所有传送的报文段都必须把ACK 置1。
    • 推送PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作。这时,发送方TCP 把PSH置1, 并立即创建一个报文段发送出去。接收方TCP收到PSH= 1的报文段,就尽快地(即“推送“ 向前)交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
    • 复位RST:当RST= 1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。RST置1还用来拒绝一个非法的报文段或拒绝打开一个连接。RST 也可称为重建位或重置位。
    • 同步SYN:在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接, 则应在响应的报文段中使SYN=1 和ACK=1。因此,SYN置为1就表示这是一个连接请求或连接接受报文。
    • 终止FIN:用来释放一个连接。当FIN= 1时,表明此报文段的发送方的数据已发送完毕, 并要求释放传输连接。
  7. 窗口:占2字节。窗口指的是发送本报文段的一方的接收窗口(而不是自己的发送窗口)。窗口值告诉对方:从本报文段首部中的确认号算起, 接收方目前允许对方发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据。

  8. 检验和:占2 字节。检验和字段检验的范围包括首部和数据这两部分。

  9. 紧急指针:占2字节。紧急指针仅在URG= 1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为零时也可发送紧急数据。

  10. 选项:长度可变,最长可达40字节。当没有使用“ 选项“ 时,TCP的首部长度是20 字节。最后的填充字段仅仅是为了使整个TCP首部长度是4字节的整倍。

    • 最大报文段长度 MSS:MSS是每一个TCP报文段中的数据字段的最大长度。
    • 窗口扩大选项
    • 时间戳选项
    • 选择确认选项

3.3 TCP 可靠传输的实现

  为了讲述可靠传输原理的方便,我们假定数据传输只在一个方向进行,即A发送数据,B给出确认。

3.3.1 确认应答机制
a. 确认应答 ACK

  TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK)。

  • 每一个ACK都带有对应的确认。
  • 确认号告诉发送端已经收到了哪些数据。
  • 确认号代表接收端下次需要接收的数据的序号。
  • 确认号代表发送端要发送的数据的序号。

如图6,主机B给主机A发送了确认号为1001,说明:序号为1000的数据(包括1000)主机B已经收到了,下一次主机A需要发送序号为1001的数据。

图6:确认应答机制
确认应答机制

b. 选择确认 SACK(了解)

  若收到的报文无差错,只是未按序到达,通过选择确认 SACK机制可以只重传缺少的数据,而不重传已经正确到达接收方的数据。

  如果需要使用选择确认 SACK,那么建立TCP连接时,就要在TCP首部中加上SACK选项,通信双方需要约定好。确认号用法不变,SACK选项用来报告收到的不连续的字节块的边界。

  因为,SACK文档未明确指出发送方如何响应SACK,所以目前仍然是重传所有未被确认的数据块。

3.3.2 滑动窗口
a. 为什么采用滑动窗口?

为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。流水线传输就是发送方可以连续发送多个分组,不必每发完一个分组就停下来等对方确认。这种方式可以获得很高的信道利用率。

TCP协议采用滑动窗口来提高信道利用率,从而提高传输效率。

TCP 的滑动窗口是以字节为单位的。


b. 滑动窗口的实现

  如图7,现假定A收到B发来的确认报文段,其中窗口是20字节,而确认号是31(表明B期望收到的下一个序号是31,而序号30为止的数据已经收到了)。

图7:A的发送窗口
A的发送窗口
发送窗口的特点:

  • 发送窗口表示:在没有收到B的确认的情况下,A可以连续把窗口内的数据都发送出去。已经发送,但未收到确认的数据都必须暂时保留,以便超时重传时使用。
  • A的发送窗口不能超过B的接收窗口数值
  • 发送方的发送窗口大小还要受到网络拥塞程度的制约。
  • 发送窗口后沿的后面部分表示已发送且已收到了确认,数据无需保留;发送窗口前沿的前面部分表示不允许发送的,因为接收方没有为这部分数据保留临时存放的缓存空间。
  • 发送窗口的位置由窗口前沿和后沿的位置共同确定。

发送窗口的变化:

  • 发送窗口后沿的变化:

    • 不动 —— 没有收到新的确认。
    • 前移 —— 收到了新的确认。
  • 发送窗口前沿的变化:

    • 向前移动
    • 不动 —— 一是没有收到新的确认,对方通知的窗口大小也不变;二是收到了新的确认但对方通知的窗口缩小了,使得发送窗口前沿刚好不动。
    • 向后收缩 —— 对方通知的窗口缩小了。TCP不赞成这样做。

  如图8,现在假定A发送了序号为31 ~ 41的数据。这时,发送窗口位置并未改变,但发送窗口内靠后面有11个字节(灰色方框)表示已发送但未收到确认。而发送窗口内靠前面的9(42~50)个字节是允许发送但尚未发送的。

图8:A发送11个字节的数据
A发送11个字节的数据
图9:A收到新的确认号,发送窗口向前滑动
A收到新的确认号,发送窗口向前滑动
图10:发送窗口内的序号都已经发送,但未被确认
图10:发送窗口内的序号都已经发送,但未被确认
描述一个发送窗口的状态需要三个指针:P1,P2和P3。指针指向字节的序号。

  • 小于P1的是已发送并已收到确认的部分, 而大于P3 的是不允许发送的部分。
  • P3 - P1 = A的发送。
  • P2 - P1 = 已发送但尚未收到确认的字节数。
  • P3 - P2 = 允许发送但当前尚未发送的字节数(又称为可用窗口或有效窗
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值