🔥个人主页: 中草药
🔥专栏:【Java】登神长阶 史诗般的Java成神之路
🎃一.运输层
运输层(Transport Layer)是OSI七层模型中的第四层,也是TCP/IP四层模型中的第三层。它的主要职责是在网络层的基础上为应用层提供端到端的数据传输服务。运输层负责管理和控制数据在网络中的传输,确保数据能够可靠地从源主机传输到目的主机。
主要功能
- 端到端通信:运输层为应用进程之间提供端到端的通信服务,它关注的是源主机与目的主机之间的通信,而不是具体的网络节点之间的通信。
- 可靠传输:提供可靠的传输服务,确保数据包按序、无误地传输。
- 流量控制:管理数据传输速率,防止发送方过快发送数据导致接收方无法处理。
- 拥塞控制:监控网络的拥堵情况,避免过多的数据包同时传输导致网络拥塞。
- 差错控制:检测并纠正数据传输中的错误。
- 多路复用与分解:将多个应用的数据合并成一个数据流进行传输,然后在接收端再将数据流分解为各个应用的数据。
- 地址映射:使用端口号来标识主机上的特定应用进程。
主要的运输层协议
-
TCP (Transmission Control Protocol):面向连接的协议,提供可靠的、有序的、无数据丢失的服务。TCP 使用三次握手建立连接,并使用四次挥手终止连接。
- 可靠性:通过确认应答、重传机制和校验和来保证数据的可靠性。
- 流量控制:使用滑动窗口机制来控制发送速率。
- 拥塞控制:通过慢启动、拥塞避免、快速重传和快速恢复等机制来避免网络拥塞。
-
UDP (User Datagram Protocol):无连接的协议,不保证数据的可靠传输,适用于对实时性要求高但对数据丢失不敏感的应用。
- 简单性:UDP 头部简单,仅有源端口、目的端口、长度和校验和四个字段。
- 广播和多播:支持广播和多播,适用于实时音频/视频传输等应用场景。
本文,我们详细探讨这两个协议
关键概念
- 端口号:用于标识主机上的特定应用进程,分为熟知端口(0-1023)、注册端口(1024-49151)和动态端口(49152-65535)。
- 套接字:组合了IP地址和端口号,用于唯一标识网络中的一个进程。
- 多路复用:运输层将多个应用的数据流合并为单一的数据流进行传输。
- 多路分解:运输层在接收端将单一的数据流分解为多个应用的数据流。
运输层与应用层的关系
运输层位于应用层之下,为应用层提供服务。应用层定义了应用程序如何使用运输层协议来发送和接收数据。例如,HTTP 协议使用 TCP 协议来传输数据,而 DNS 查询通常使用 UDP 协议。
🎄二.UDP协议
UDP (User Datagram Protocol) 是一种无连接的传输层协议,用于在网络上传输数据包。与TCP (Transmission Control Protocol) 不同,UDP 提供了一种轻量级的数据传输方式,适用于那些对速度要求较高但对数据丢失不太敏感的应用场景。
- 16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度(最大为64kb)
- 如果校验和出错,会直接丢弃
特点
- 无连接:UDP 在发送数据之前不需要建立连接,知道对端的IP和端口号就直接进行传输,因此减少了通信延迟。
- 不可靠:UDP 不保证数据包的可靠传输,也不保证数据包的顺序到达。这意味着数据包可能会丢失、重复或乱序。
- 面向数据报:不能够灵活的控制读写数据的次数和数量。例:
如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100 个字节; 而不能循环调用10次recvfrom, 每次接收10个字节
- 低开销:UDP 的头部开销较小,仅为8字节,这使得它比TCP更适合实时应用,如视频流媒体和在线游戏。
- 广播和多播支持:UDP 支持向多个目的地发送数据包,这对于需要广播或多播的应用非常有用。
工作原理
- 发送数据:发送方将数据封装成UDP数据报(datagram),并添加源端口、目的端口、长度和校验和等字段。
- 接收数据:接收方接收到UDP数据报后,根据目的端口将数据传递给相应的应用程序。
- 校验和:UDP 包含一个可选的校验和字段,用于检测数据包在传输过程中的错误。
基于UDP的应用层协议
- NFS:网络文件系统
- TFTP:简单文件传输协议
- DHCP:动态主机配置协议
- BOOTP:启动协议(用于无盘设备启动)
- DNS:域名解析协议
应用场景
- 实时音频/视频传输:由于UDP具有较低的延迟,适合实时通信应用。
- 在线游戏:对于需要快速响应的游戏,UDP的低延迟特性使其成为理想的选择。
- DNS查询:域名系统(DNS)通常使用UDP进行查询,因为大多数DNS查询都是短小且不需要确认的。
- 多播应用:多播(Multicast)允许一个数据包同时发送给多个接收者,非常适合多媒体流等应用。
优势和劣势
优势:
- 低延迟:无需建立连接,减少了握手的时间。
- 低开销:头部简单,处理速度快。
- 广播和多播支持:非常适合需要向多个目标发送数据的情况。
劣势:
- 数据包丢失:没有重传机制,数据包可能会丢失而不被发现。
- 无序接收:数据包可能不会按照发送顺序到达。
- 无流量控制:发送方不能控制接收方的接收能力,可能导致数据包丢失。
示例代码
UDP客户端
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
private DatagramSocket socket=null;
private String serverIP;
private int serverPort;
public UdpEchoClient(String serverIP,int serverPort) throws SocketException {
socket=new DatagramSocket();
this.serverIP=serverIP;
this.serverPort=serverPort;
}
public void start() throws IOException {
System.out.println("启动客户端");
Scanner sc=new Scanner(System.in);
while(true){
// 1. 从控制台读取到用户的输入.
System.out.print("->");
String request=sc.next();
// 2. 构造出一个 UDP 请求, 发送给服务器.
DatagramPacket requestPacket=new DatagramPacket(request.getBytes(), request.getBytes().length,
InetAddress.getByName(this.serverIP),this.serverPort);
socket.send(requestPacket);
// 3. 从服务器读取到响应
DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
socket.receive(responsePacket);
String response=new String(responsePacket.getData(),0,responsePacket.getLength());
// 4. 把响应打印到控制台上.
System.out.println(response);
}
}
public static void main(String[] args) throws IOException{
UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);
client.start();
}
}
UDP服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;
/**
* Udp 无连接 不可靠传输 面向数据报 全双工
*/
public class UdpEchoServer {
private DatagramSocket socket=null;
public UdpEchoServer(int port) throws IOException{
socket=new DatagramSocket(port);
}
//通过start启动服务器的核心流程
public void start() throws IOException {
System.out.println("服务器启动");
while(true){
//此处通过死循环不断处理 客户端 的请求
//1.读取客户端的请求并解析
DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
socket.receive(requestPacket);
// 上述收到的数据, 是二进制 byte[] 的形式体现的. 后续代码如果要进行打印之类的处理操作
// 需要转成字符串才好处理.
String request=new String(requestPacket.getData(),0,requestPacket.getLength());
// 2. 根据请求计算响应, 由于此处是回显服务器. 响应就是请求.
String response=process(request);
// 3. 把响应写回到客户端
DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),
response.getBytes().length,requestPacket.getSocketAddress());
socket.send(responsePacket);
// 4. 把日志打印一下.
System.out.printf("[%s:%d] req=%s, resp=%s\n", requestPacket.getAddress(),
requestPacket.getPort(), request, response);
}
}
public String process(String request){
return request;
}
public static void main(String[] args) throws IOException {
UdpEchoServer server=new UdpEchoServer(9090);
server.start();
}
}
🧨三.总结与反思
书的真正目的在于诱导头脑自己去思考。——莫利
通过学习UDP,我了解到这是一种轻量级、无连接的传输层协议,适用于对实时性要求较高的应用。尽管UDP存在数据包丢失和顺序问题,但在很多应用场景中,它的低延迟和低开销特性使其成为一个非常合适的选择。在实际开发中,我们需要根据具体需求选择合适的传输协议,并在应用层实现必要的容错机制,以弥补UDP本身的不足之处。通过理论学习与实践相结合,我对UDP有了更深入的理解,并能够在未来的项目中更好地应用这一协议。
-
理解协议的本质:
- 在学习UDP的过程中,理解其设计哲学是非常重要的。
- UDP的设计初衷是为了提供一种轻量级的数据传输方式,适用于那些对延迟敏感但对数据完整性和顺序性要求不高的应用场景。
-
实际应用中的考量:
- 在实际应用中,需要综合考虑UDP的优势和劣势。
- 对于那些对延迟要求极高的应用,UDP是一个非常好的选择;但对于需要高可靠性的应用,则需要考虑使用TCP或其他可靠性更高的协议。
-
动手实践的重要性:
- 通过编写UDP的客户端和服务器端程序,可以更好地理解和掌握UDP的工作原理。
- 实践中遇到的问题可以帮助加深对协议的理解,同时也能够锻炼解决问题的能力。
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐
制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸