终于来到了传输层,这个面试问的最多了
传输层
TCP/IP中有两个具有代表性的传输层协议,分别为:
- TCP: 提供可靠的通信传输
- UDP:用于让广播和细节控制交给应用的通信传输
根据通信的具体特征,选择合适的传输层协议非常重要。
套接字(Socket):
使用TCP或UDP时,会广泛使用到套接字(socket)的API。套接字原本是由BSD UNIX开发的,但是后被移植到了Windows的Winsock以及嵌入式操作系统中。
应用程序利用套接字,可以设置对端的IP地址、端口号,并实现数据的发送与接收。
端口号
数据链路和IP中的地址,分别指的是MAC地址和IP地址。
前者用来识别同一链路中不同的计算机,后者用来识别TCP/IP网络中互连的主机和路由器。
同样的,在传输层中也有类似于地址的概念,那就是端口号。
端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。
另:仅凭目标端口识别某一个通信是远远不够的。通常采用5个信息来识别一个通信。它们分别是:
- 源IP地址
- 目标IP地址
- 协议号 :在IP协议部分我们提到IP首部中有一个协议字段,用来标识网络层(IP)的上层所采用的是哪一种传输层协议。根据这个字段的协议号,就可以识别IP传输的数据部分究竟是TCP的内容,还是UDP的内容。
- 源端口号
- 目标端口号
端口号如何确定
- 标准既定的端口号
也叫静态方法。是指每个应用程序都有其指定的端口号。但不是说可以随意使用任何一个端口号。每个端口号都有其对应的使用目的。
例如,HTTP、TELNET、FTP等应用协议使用的知名端口号:
- 时序分配法
也叫动态分配法。服务端有必要确定监听端口号,但是客户端没必要确定端口号。
这种方法下,客户端不用自己设置端口号,而全权交给操作系统进行分配。操作系统可以为每个应用程序分配互不冲突的端口号。这种动态机制,即使同一个客户端程序发起多个TCP连接,识别这些通信连接的部分数字也不会全部相同。动态端口号取值范围在49152到65535之间。
端口号与协议
端口号由其使用的传输层协议决定。因此,不同的传输协议可以使用相同的端口号。例如,TCP与UDP使用同一个端口号,但使用目的各不相同。这是因为端口号上的处理会根据每个传输协议的不同而进行的。
数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块。
UDP
UDP是User Datagram Protocol 的缩写。
UDP是利用IP提供面向无连接的通信服务,不提供复杂的控制机制。
并且它是将应用程序发来的数据在收到的那一刻,立刻按照鸳鸯发送到网络上的一种机制。
即使是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥堵的行为。此外,传输途中即使出现丢包,UDP也不负责重发。甚至当出现包的到达顺序乱掉是也没有纠正的功能。
如果需要这些细节控制,那么不得不交有采用UDP的应用程序去处理。
由于UDP面向无连接,他可以随时发送数据。再加上UDP本身的处理既简单又高效,因此常用于以下几个方面:
- 包总量较小的通信(DNS、SNMP等)
- 视频、音频等多媒体通信(即时通信)
- 限定于LAN等特定网络中的应用通信
- 广播通信(广播、多播)
UDP 首部
如下图,除去数据的部分就是UDP的首部。
UDP的首部源端口号,目标端口号,包长和校验和组成。
- 源端口号: 标识发送端端口号,字段长16位。该字段可以不设置,缺省值为0,可用于不需要返回的通信中。
- 目标端口号: 标识接收端端口号,字段长16位。
- 包长度: 指UDP首部的长度和数据的长度之和。为8位字节。
- 检验和: 校验和用来判断数据在传输过程中是否损坏。计算这个校验和的时候,不仅考虑源端口号和目标端口号,还要考虑 IP 首部中的源 IP 地址,目标 IP 地址和协议号(这些又称为 UDP 伪首部)。这是因为以上五个要素用于识别通信时缺一不可,如果校验和只考虑端口号,那么另外三个要素收到破坏时,应用就无法得知。这有可能导致不该收到包的应用收到了包,改收到包的应用反而没有收到。
这个概念同样适用于即将介绍的 TCP 首部,但是TCP的校验和无法关闭。
TCP
与UDP不同,TCP则"人如其名",可以说是对"传输、发送、通信"进行"控制"的"协议"。
TCP充分实现了数据传输时各种控制功能,可以进行丢包是的重发控制,还可以对次序乱掉的分包进行顺序控制。
此外,TCP作为一种面向连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。
连接
连接是指各种设备、线路,或网络中进行通信的两个应用程序为了相互传递消息而专有的、虚拟的通信线路,也叫做虚拟电路。
一旦建立了连接,进行通信的应用程序只是用这个虚拟的通信线路发送和接收数据,就可以保障信息的传输。应用程序不用顾虑IP网络上可能发生的各种问题,依然可以转发数据。
TCP则负责控制链接的建立、断开、保持等管理工作。
TCP 首部
和 UDP 首部相比,TCP 首部要复杂得多。解析这个首部的时间也相应的会增加,这是导致 TCP 连接的效率低于 UDP 的原因之一。
其中某些关键字段解释如下:
序列号: 字段长32位。它表示发送数据的位置,假设当前的序列号为 s,发送数据长度为 l,则下次发送数据时的序列号为 s + l。在建立连接时通常由计算机生成一个随机数作为序列号的初始值。
确认应答号: 字段长32位。它等于下一次应该接收到的数据的序列号。假设发送端的序列号为 s,发送数据的长度为 l,那么接收端返回的确认应答号也是 s + l。发送端接收到这个确认应答后,可以认为这个位置以前所有的数据都已被正常接收。
数据偏移: TCP 首部的长度,单位为 4 字节。如果没有可选字段,那么这里的值就是 5。表示 TCP 首部的长度为 20 字节。
保留: 该字段为以后拓展时使用,其长度为4位。一般设置为0,但即使受到的包在该字段不为0,此包也不会被丢弃。
控制位: 改字段长度为 8 比特,分别有 8 个控制标志。依次是 CWR,ECE,URG,ACK,PSH,RST,SYN 和 FIN。
CWR: 与后面的ECE标志都用于IP首部的ECN字段。ECE标志为1时,则通知对方已将拥塞窗口缩小。
ECE: 表示ECN-Echo。置为1会通知通信对方,从对方到这边的网络有拥塞。在收到数据包的IP首部中ECN为1时将TCP首部中的ECE置为1。
URG: 此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据;
ACK: 此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;
PSH: 这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;
RST: 这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;
SYN: 表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手;
FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
窗口大小:该字段长16位。用于表示从应答号开始能够接受多少个 8 位字节。如果窗口大小为 0,可以发送窗口探测。
紧急指针: 仅在 URG 控制位为 1 时有效。表示紧急数据的末尾在 TCP 数据部分中的位置。通常在暂时中断通信时使用(比如输入 Ctrl + C)。
选项: 该字段长度最大为40字节,用于提高TCP的传输性能。选项字段尽量调整其为32位的整数倍。
TCP与UDP的区别
TCP是面向连接的、传输可靠(保证数据正确性且保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。
TCP是一种流模式的协议,是面向连接的,也就是说,在连接持续的过程中,Socket 中收到的数据都是由同一台主机发出的(劫持什么的不考虑),因此,知道保证数据是有序的到达就行了,至于每次读取多少数据不关心。
TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。
UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。
关于TCP是一种流模式的协议,UDP是一种数据报模式的协议,这里要说明一下,TCP是面向连接的,也就是说,在连接持续的过程中,socket 中收到的数据都是由同一台主机发出的(劫持什么的不考虑),因此,知道保证数据是有序的到达就行了,至于每次读取多少数据自己看着办。
而UDP是无连接的协议,也就是说,只要知道接收端的IP和端口,且网络是可达的,任何主机都可以向接收端发送数据。这时候,如果一次能读取超过一个报文的数据,则会乱套。比如,主机A向发送了报文P1,主机B发送了报文P2,如果能够读取超过一个报文的数据,那么就会将P1和P2的数据合并在了一 起,这样的数据是没有意义的。