一、前言
1.1 再次理解传输层
传输层是计算机网络中的一层,位于网络层和应用层之间。它主要负责在网络中的两个端系统之间提供可靠的、端到端的数据传输服务。简单理解,传输层就是负责在源主机和目标主机之间提供端到端的数据传输。
传输层的两个主要协议有传输控制协议(TCP)和用户数据报协议(UDP)两种。
- 传输控制协议(TCP):
- TCP是一种面向连接的协议,提供可靠的、有序的数据传输。它确保数据按照发送的顺序被接收,并提供差错检测和重传机制以确保数据的可靠性。
- 一个常见的TCP的示例用途是网页浏览器通过HTTP协议进行网页请求。当你在浏览器中访问一个网页时,浏览器会与服务器建立一个TCP连接,然后使用该连接传输HTML、图片和其他资源数据,确保这些数据按照正确的顺序到达,以显示完整的网页。
- 用户数据报协议(UDP):
- UDP是一种无连接的协议,不提供可靠性保证,但传输效率较高。它将数据分割成数据报,每个数据都是独立的,可以独立传输,因此没有复杂的连接建立和维护过程。
- 一个常见的UDP的示例用途是音视频流传输。在语音通话或视频聊天中,为了实时传输数据,能够立即播放声音或图像,UDP被广泛使用。尽管UDP可能会丢失一些数据包,但对于实时通信来说,及时性比可靠性更重要。
上述示例只是传输层协议在网络中的部分应用示例。传输层还有其他更广泛的用途,如文件传输、电子邮件传输等。无论使用TCP还是UDP,传输层的目标是确保数据在源和目标之间有效且可靠的传输,同时提供所需的服务质量。
1.2 再次理解端口号
端口号(Port)标识了一个主机上进行通信的不同的应用程序。在TCP/IP协议中,用“源IP”,“源端口号”,“目的IP”,“目的端口号”,“协议号”这样一个五元组来标识一个通信(可以通过netstat-n查看)。
我们来仔细思考一下其中的细节:IP地址标识了全网里唯一一台主机。Port端口号标识了一台机器上的一个应用程序,也可以理解为Port端口号标识了一台机器上的唯一一个进程(一个端口号只能绑定一个进程)。IP地址和Port端口号不就是标识了全网里唯一进程吗!!!网络通信本质上不就是进程间通信吗?那么现在再回过头看“源IP”,“源端口号”,“目的IP”,“目的端口号”,“协议号”这样一个五元组来标识一个通信也就不难理解了。
1.2.1 端口号范围划分
端口号范围划分是为了网络通信中识别和区分不同的应用程序或服务而定义的。根据传输层协议的不同,端口号的范围也是有所区别的。
在TCP和UDP协议中,端口号范围被划分为以下几类:
- 知名端口(Well Known Ports):从0到1023的端口号被预留给一些常见的服务或应用程序使用,如HTTP(端口号80)、FTP(端口号21)等。这些端口号在整个互联网上是公认的,并且只能由特权用户(如管理员)打开。
-
注册端口(Registered Ports):从1024到49151的端口号被分配给用户注册的应用程序和服务。这些端口号可以被普通用户打开,但应该避免与已知的知名端口冲突。
-
动态/私有端口(Dynamic/Private Ports):从49152到65535的端口号是动态或私有端口,用于临时的、非注册的应用程序和服务。这些端口号可以被任何用户的应用程序使用,通常用于客户端与服务器之间的临时通信。
需要注意的是,端口号的范围划分并不是严格规定的,而是一种通用的约定。在实际应用中,为了避免冲突和提高安全性,建议遵循这种范围划分并选择未使用的端口号进行应用程序的开发和部署。
1.2.2 认识知名端口号
当提到知名端口号时,我们指的是一些常用的端口号,这些端口号在整个互联网上是公认的,并且被用来提供特定的网络服务。以下是一些常见的知名端口号及其对应的服务:
- 20/TCP, 21/TCP: FTP(文件传输协议)数据传输和控制
- 22/TCP: SSH(安全外壳协议),用于安全远程登录和文件传输
- 23/TCP: Telnet(远程终端协议),用于远程管理、终端访问
- 25/TCP: SMTP(简单邮件传输协议),用于电子邮件的发送
- 53/TCP,UDP: DNS(域名系统),用于将域名解析为IP地址
- 67/UDP, 68/UDP: DHCP(动态主机配置协议),用于自动分配IP地址、网关等网络配置信息
- 25/TCP: SMTP(简单邮件传输协议),用于电子邮件的发送
- 53/TCP,UDP: DNS(域名系统),用于将域名解析为IP地址
- 67/UDP, 68/UDP: DHCP(动态主机配置协议),用于自动分配IP地址、网关等网络配置信息
- 443/TCP: HTTPS(超文本传输安全协议),用于通过安全的加密连接进行Web通信
- 3389/TCP: RDP(远程桌面协议),用于远程访问和控制计算机桌面
这些端口号只是一部分知名端口号,实际上还有许多其他的端口号用于提供各种特定的网络服务。
我们可以通过cat/etc/services查看知名端口号。
1.3 网络常用指令 netstat 与 pidof
netstat(Network Statistics)是一个用于显示网络连接、路由表和网络接口等相关信息的命令。它可以提供以下方面的详细信息:
- 网络连接状态:显示当前计算机与其他设备之间的所有活动网络连接,包括TCP连接、UDP连接、监听端口等。
- 路由表:显示系统的 IP 路由表,其中包含数据包如何被转发的信息。
- 网络接口:显示计算机上的所有网络接口,例如以太网、Wi-Fi、回环接口等。
- 进程标识符(PID):可以通过"-p"选项将每个连接的相关进程ID(PID)显示出来,从而了解哪个进程正在使用某个特定的网络连接。
具体选项如下:
netstat -a // 显示所有活动的网络连接和监听端口
netstat -n // 以数字格式显示所有连接
netstat -p // 显示与连接关联的进程ID
netstat -t // 显示TCP连接
netstat -u // 显示UDP连接
netstat -l // 显示Listen(监听)的服务
pidof命令用于根据进程名来查找运行中的进程的PID(进程标识符)。 常用用法:pidof+进程名,来查询进程的PID。
二、UDP协议
2.1 UDP协议的报文
我们直接先来学习一下UDP的报文,如下图:
根据上图,我们能很好的总结出UDP报文的结构如下:
UDP报文头部(固定8字节):
- 源端口(源端口号,2字节):表示发送端的端口号。
- 目的端口(目的端口号,2字节):表示接收端的端口号。
- UDP长度(2字节):表示UDP报文的长度,包括头部和数据部分。
UDP校验和(2字节):用于验证UDP报文的完整性,检测是否出现传输错误。
数据部分: UDP报文的数据部分可以包含任意大小的数据(可以没有),没有固定的格式要求。它是应用层传递给UDP协议的数据,在传输过程中,UDP会将整个数据部分封装为UDP报文并发送。
任何协议都要解决的两个问题:1、如何分离和封装;2、如何向上交付。
怎么分离和封装呢?首先UDP报头是有固定长度的,这就很好的解决了。怎么理解UDP报文的报头呢?其实UDP报头在底层就是用一个结构体来封装的,再加上位段就可以很好的实现对UDP报头的封装。代码如下
struct udp_hdr
{uint32_t source:16; // 源端口号uint32_t dest:16; // 目标端口号uint32_t len:16; // UDP报文长度(包括报头和数据部分)uint32_t check:16; // 校验和
};
UDP的报头加上传输数据不就是UDP报文吗!分离时报头中有报文长度字段,直接减去报头的8个字节,剩下的就是所传输的数据。
向上交付也不难,有目的端口和目的IP地址,就可以很好的找到目标进程进而传输数据。
2.2 UDP的特点
UDP(User Datagram Protocol,用户数据报协议)是一种在网络通信中常用的传输层协议。与TCP(Transmission Control Protocol,传输控制协议)不同,UDP是一种无连接协议,它提供了一种简单的、不可靠的数据传输服务。
UDP的特点:
-
无连接性:UDP是一种无连接协议,发送方不需要在发送数据之前与接收方建立连接。每个UDP数据报都是独立的,有自己的头部信息,可以独立地进行传输。这种无连接性使得UDP具有较低的传输延迟和较小的开销。
-
不可靠性:UDP不提供数据包的可靠交付。一旦发送数据,UDP就不会对数据包进行确认或重新发送丢失的数据包。这意味着UDP在数据传输过程中可能会发生数据包丢失、重复、乱序等情况。因此,如果应用对数据传输的可靠性要求较高,则不适合使用UDP。
-
高效性:由于UDP无需建立连接和维护状态信息,因此它的开销较小,数据报的头部相对较小。同时,UDP也不会进行拥塞控制,因此在网络负载较大时,UDP可以更高效地传输数据。
-
面向数据报文:UDP把应用层交给传输层的报文信息进行封装,形成UDP数据报进行传输。这意味着UDP在传输过程中不会对数据进行拆分和合并,保持了数据的完整性。
面向数据报的简单理解:应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并。用UDP传输100个字节的数据,如果发送端调用一次sendto, 发送100个字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节。 而不能循环调用10次recvfrom, 每次接收10个字节。
需要注意的是,由于UDP的不可靠性和无连接性,它在某些情况下可能会导致数据丢失或乱序。
这里需要注意的是,UDP的不可靠并非是一个缺点,也并非是贬义词。只是在相比之下,与UDP相对的是TCP(Transmission Control Protocol),它是一种可靠的协议,提供了数据传输的可靠性和顺序性。但UDP协议的简洁和低延迟特性使其在某些特定的应用场景中具有一定的优势。
2.3 UDP的缓冲区
UDP没有真正意义上的发送缓冲区。调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作
UDP具有接收缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了, 再到达的UDP数据就会被丢弃。
UDP的socket既能读也能写,这个概念叫做全双工。所谓全双工通信是指同时实现双方之间的双向数据传输,即在同一时间既能发送数据也能接收数据。
UDP协议本质上是一种简单的数据报传输协议,它不维护连接状态,也不提供可靠性保证和流控制。每个UDP数据报都是独立的,它们相对独立地发送和接收,不会受到之前或之后数据报的影响。