第四层 传输层

概览

Transport Layer

使用数据段。基于端口。

第四层可以校验数据的可靠性,如果一方发给另一方的数据出错,接收方会在第四层要求对方重传数据。

第四层还可以做流控制,使得数据传输的速度适合慢的主机。

协议

第四层的两个代表性的协议是TCP和UDP协议。

TCP即Transmission Control Protocol,而UDP是User Datagram Protocol。两者有着共同点就是都是把上层来的数据进行分段后一段一段传输。两者区别是:

  • TCP是可靠传输,逻辑上是面向连接的,需要通讯前经过三次握手建立连接关系,通讯过程中还会经常确认,结束时会经过四次握手解除连接关系。TCP对数据的校验更为准确也更复杂,对数据正确性要求很高。如果接收方确定接收到正确的数据,还要发回确认信号。TCP还可以进行流控制。
  • UDP是不可靠传输,并不在通讯前建立连接关系。校验的步骤也很简单,不会做确认。也不会做流控制。速度比TCP快。

端口

但无论哪个第四层协议,都是使用端口建立进程之间的连接的。

网络操作系统对多个要求上网的进程所使用的是分时复用的方案,会分出许多不同的端口供服务进程使用。

端口作为一个数据占2个字节,取值从0到65535。这就意味着同一主机可以有很多不同的进程同时上网。

端口大致可以分为以下几类:

  • public: 0~255 这些端口分给公认的服务进程,如FTP的端口为21,SMTP为25,DNS为53,HTTP为80等等。
  • well-known: 0~1023 这些端口分给熟知的服务进程,也有一定规范。
  • 1024~49151: 这些端口预留给其他进程登记使用。
  • 49152~65535: 这些端口都是短暂端口,进程进行时随机使用。

所有要上网的应用进程都需要有端口号。

第四层的通讯单位称为Socket,结构是(IP_address, port),也就是既有IP又有端口号。而一个连接也可以用源Socket和目的Socket来描述。

TCP协议中不支持多播和广播。

TCP协议

特点:可靠传输,流控制,连接管理。

TCP数据段结构

TCP数据段由前面的首部和后面的数据部分组成。

首部结构:

如图,前二十字节是固定首部,后面还有可变长度的一段内容。

  • 源端口和目的端口:描述连接的两个端口号,各占2字节。
  • 序号:4字节。TCP传输时会把数据每个字节都标号,序号字段是本报文段所发送的数据的第一个字节的序号。
  • 确认号:4字节。是期望受到对方的下一个报文段的数据的第一个字节的序号。
  • 数据偏移:占4位,记录首部的总长度。以4字节为单位。因此可变部分不满4字节的时候还需要一段填充。
  • 保留:预留给以后可能设计的新功能。
  • 6个标记位:
    • URG:紧急状态位,为1时启动紧急状态,同时紧急指针也启用。紧急指针用于指示将紧急数据和普通数据分开。
    • ACK:1时确认号字段有效。0时确认号字段无效(一开始未初始化的时候。)
    • PSH:push位。如果这一位为1,则设备马上对本段进行发送或者送给上层应用。
    • RST:Reset位。为1时表示连接中有严重的错误,必须释放连接然后重新建立连接。有时候也会用于拒绝连接。
    • SYN:为1时表示这是一个连接请求或者连接接受报文,在初始化的时候出现。
    • FIN:为1时表示“我不会再主动发送数据”,准备结束连接的时候使用。
  • 窗口:占有两个字节,向对方说明目前自己还能够接受处理多少个字节的内容(通常又缓存剩余空间决定)这一概念在后面还会详细阐述。
  • 校验和:两个字节长。这次的校验和校验范围同时包含首部和数据两个部分。
  • 紧急指针:两个字节,指示紧急部分到哪里之前为止。当紧急状态位为1时才有用。
  • 选项:一些可选信息。长度可变。
  • 填充字段:保证首部的字节数为4的倍数,全0填充。

所以一个数据段由一个至少20字节长的首部和数据部分构成。

建立连接

两台主机采用TCP协议建立连接要三次握手实现。

具体过程如图:

一般是服务器一直处于一个监听的状态,然后由客户端主动发出连接请求。图中的seq表示数据段首部的序号字段,而ack表示数据段首部的确认号字段。详细过程即:客户端先发送连接同步请求,如果服务器不同意就会将RST状态位置为1发回,表示拒绝;如果同意就发回应答。然后客户端受到应答之后再对应答做确认,发回。

值得注意的是,之后的数据传输一般还是客户端开始发信,而且seq和ack和第三次握手是一样的。所以现在有时候会在第三次握手的时候顺便携带一些数据,避免一次无用的发信。但是考试认为,这三次握手都是不携带数据部分的。

TCP传输控制

TCP为了可靠的传输,传输的内容总是需要接收方做确认。

发送方发送数据后,会为这次发送启动一个重传计时器,如果计时器到时了还没有收到接收方的回复就会重新发送一遍数据。

为了传输的效率,通常会采用流水线式的发送方法。如图:

值得注意的是,虽然图中是这么画的,但是事实上并不是发送方要对每一个接收的数据段做确认,也可以一个回复就能确认之前好几个接受的数据段的内容,这就由ack确认号字段实现了。

这里看到,接收方的窗口信息可以告知发送方最多还能再发送多少字节的内容。发送方依据窗口信息来组织发送,避免出现发送信息过快对方无法及时处理的情况。下图更清晰地说明了窗口的作用:

下面是一个综合的例子。

断开连接

断开连接需要四次握手。如图:

详细过程:一般是客户端主动发送断开连接的请求,表示“我”已经不会再主动发送信息了。服务器收到后做确认。但是到此位置可能服务器还有要发送的内容没有完成,因此客户端不会立刻离开,而是等待服务器发送完数据(这些数据依然被客户端正常处理)后也发送结束请求。在收到服务器发来的结束请求后客户端发回确认。但是客户端依旧不会离开,因为这条确认信息可能存在丢失的风险,一旦丢失,服务器就会在一段时间等待后重传刚才的结束申请。因此客户端通常会再等待一段时间。

TCP计时器

在上面的过程中,TCP协议用到了四种计时器:

  • 重传计时器:发送后启动。计时器到时后重传刚才的数据。
  • 坚持计时器:避免死锁,即收到窗口为0的数据段之后,发送方将等待对方处理数据,直到对方发来窗口不为0的信息。但是对方这段信息可能会丢失,一旦丢失,发送方将陷入一直等待的状态,这就是死锁。坚持计时器在收到窗口为0的数据段后开启,到时后主动发送信息询问接收方的窗口情况。
  • 保持计时器:数据传输停滞时启动,到时后还没有收到新的数据段就会和对方协商是不是可以断开连接了。
  • 时间等待计时器:断开连接后最后一次握手的发送方的等待。最后一次握手发出时开启,除非到时之前又收到新数据段,否则到时后关闭客户端。

TCP有限状态机

仅供参考,无需深入探究:

UDP协议

即用户数据报协议。特点是无连接,不可靠,不做差错处理,没有逻辑控制,但是达到了以更快的速度和更小的开销在网络中传输数据的目的。现在在流媒体传输和RIP、DNS、SNMP、TFTP、DHCP技术中使用。如果要广播或者组播,也只能使用UDP。

UDP数据段结构:

0~15 16~31 32~47 48~63 64~
Source Port Des Port Length Check Sum Data…

可见,首部是固定的八个字节长。这里的校验和同时校验首部和数据部分。

UDP的逻辑十分简单,对上层传来的数据报文会直接转发,不做拆分处理。因此可能需要使用UDP协议的上层应用实现做好划分,避免一个数据段太长。

NAT/PAT技术

这两种技术都是转换内网地址和公网地址的技术。由于IP资源的短缺,许多局域网内部可能使用私有IP。但是如果要和外面的主机交流的话,私有IP是不能上Internet的,需要一个全局IP来代言。这两种技术可以将内网的私有IP地址映射为一个全局IP地址。

NAT/PAT技术分为三类:

  • 静态NAT:固定的内网地址和全局地址的映射。事先写死,一一映射。缺点是并没有解决IP短缺的问题,只是简单的做了一个转换。
  • 动态NAT:事先有一个全局IP池,里面有固定数量的可用全局IP地址。内网主机想上网时发出申请,路由器为其分配一个临时的全局IP。优点是,如果不会同时有超过IP池大小的主机上网,那么不会产生冲突,众多主机可以共享数量较少的全局IP地址,节约了IP地址。但是缺点也显而易见,当同时要上网的主机数量超过IP池容量,就只能委屈某些主机。
  • PAT:只用一个全局IP地址,把内网的IP和端口映射到这一个全局IP的不同端口上。现在的主要方案。

还有一点值得说的就是技术中的地址类型:

  • Inside Local Address 内网IP地址(和端口号),私有的IP,不能直接发到Internet上。
  • Inside Global Address 注册IP地址(和端口号),转换后可以发到Internet上的IP地址,是全局IP地址。内网IP映射的结果。
  • Outside Global Address 外网IP地址(和端口号),和外界沟通的目的IP地址。
  • Outside Local Address 外部本地地址。事实上外部主机的地址也有可能被网关路由器修改(比如在icmp报文发送返回确认的时候,可能需要修改端口号来保持和发送方的端口号一致),所以这个外部本地意味着路由器展示给主机的外部IP地址和端口号。