【网络】-UDP原理及编程

本文介绍了UDP协议的基本概念,包括其与TCP协议的区别,如无连接、不可靠的特性。文章详细讲解了UDP数据报的格式,强调了CRC校验和的作用,并探讨了UDP的特点。此外,还提供了基于Java的UDP回显服务器的编程示例,展示了如何使用DatagramSocket和DatagramPacket进行UDP通信。

本篇学习UDP原理及基础编程


传输层

传输层负责数据能够从发送端传输接收端。

传输层的重点协议

而传输层的重点协议为TCP协议和UDP协议
TCP,即Transmission Control Protocol,传输控制协议。人如其名,要对数据的传输进行一个详细的控制。
UDP(User Datagram Protocol,用户数据报协议)是一种网络传输层协议,它提供了一种无连接的、不可靠的数据传输服务。

TCP协议和UDP协议的区别

两个协议的区别:
首先两种协议都是传输层协议
UDP协议:
无连接:使用UDP通信的双方,不需要刻意保存对端的相关信息。直接投递,不需要接受连接,就能通信
不可靠传输:消息发送,不关注结果
面向数据报:以一个UDP数据报为基本单位
全双工:一条路径,双向通信

TCP协议:
有连接:使用TCP通信的双方,则需要刻意保存对端的相关信息。需要先把连接接受,才能通信
可靠传输:尽可能的传输过去(知道自己是否传输成功)
面向字节流:以字节为传输的基本单位,读写方式非常灵活
全双工:一条路径,双向通信

半双工:单向通信

 本篇主要对UDP的协议格式以及编程进行学习

UDP

UDP的概念

UDP(User Datagram Protocol,用户数据报协议)是一种网络传输层协议,它提供了一种无连接的、不可靠的数据传输服务。与TCP(Transmission Control Protocol,传输控制协议)相比,UDP更简单、速度更快,但也更不可靠。
UDP是传输层的一种协议

UDP数据报格式

UDP数据报 = 报头+载荷
报头包含四个字段,每个字段两个字符(源端口,目的端口,报文长度,校验和)
载荷为:应用层数据报

在这里插入图片描述
在这里插入图片描述
注意:
一个UDP报文最大长度就是64kb
使用UDP编程时要注意udp数据报不能太长,否则会有问题

校验和:网络传输并非那么稳定,存在的意义就是,用来判定一下传输的数据是否出错
把载荷数据,带入到校验和算法中,计算生成的校验和;

验和结果
校验和不对,此时数据一定是错的,如果校验和是对的,但是数据也有一定概率是错的
为了让校验和能够识别率更高一些,计算的和通常会以数据内容作为参数来计算,数据内容发生变化,校验和也会变化,
而校验和往往是取内容/内容的一部分,通过一些算数运算,数学公式转换,得到一个数值,如果内容改变,校验和也会改变
前提:输入的内容一样,按照同一个算法得到的校验和,结果也是一样的
UDP这里使用的是CRC算法

CRC

CRC(Cyclic Redundancy Check)是一种常用的数据校验算法,用于检测和纠正数据传输中的错误。

CRC 算法基于多项式除法,通过对数据块进行除法运算并计算出一个校验值。发送方在发送数据前计算校验值,并将数据和校验值一起发送给接收方。接收方在接收到数据后,同样进行除法运算并计算出一个校验值,然后与接收到的校验值进行比较,如果两者相等,则说明数据没有发生错误;如果不相等,则说明数据存在错误。

CRC 算法的实现通常使用一个固定的生成多项式(通常表示为一个二进制数),例如CRC-CCITT采用的是0x1021。算法过程中,发送方和接收方要保持一致的生成多项式,以保证正确的校验。

CRC 算法具有高效、可靠的特点,广泛应用于数据通信、存储介质、网络传输等领域,常用于校验数据包的完整性和准确性。

UDP的特点

无连接
知道对端的IP和端口号就直接进行传输,不需要建立连接;

不可靠
没有任何安全机制,发送端发送数据报以后,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息;

面向数据报
应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并;
用UDP传输100个字节的数据:
如果发送端一次发送100个字节,那么接收端也必须一次接收100个字节;而不能循环接收10次,每次接收10个字节。

缓冲区
UDP只有接收缓冲区,没有发送缓冲区:

扩展问题

UDP本身是无连接,不可靠,面向数据报的协议,如果要基于传输层UDP协议,来实现一个可靠传输,应该如何设计?
UDP大小是受限的,如果要基于传输层UDP协议,传输超过64K的数据,应该如何设计?
答:

  1. 引入序列号,保证数据顺序;
  2. 引入确认应答,确保对端收到了数据;
  3. 引入超时重传,如果隔一段时间没有应答,就重发数据;

UDP编程

基于UDP的api

DatagramSocket :
socket是文件;Datagram就是数据报。
Socket,说明这个对象是Socket对象(Socket对象对应到系统中一个特殊的文件‘Socket文件’,这个文件对应的并非硬盘上的某个数据存储区域,而是网卡这个硬件设备)
要想操作网络通信,就需要Socket文件这样的对象,借助这个Socket文件对象,来间接操作网卡
往这个Socket对象中写数据,相当于通过网卡发送消息
往这个Socket对象中读数据,相当于通过网卡接收消息

DatagramSocket 构造方法:
在这里插入图片描述
此处的socket对象肯被客户端/服务器都使用。服务器这边的socket往往需要关联一个具体的端口号,客户端这边则不要手动指定,系统自动分配就可以。
socket也是文件,使用过后需要关闭,否则就会出现文件泄露的问题。

DatagramSocket 方法:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

DatagramPacket:
这个对象是一个UDP数据报,····是要传输的数据

DatagramPacket是UDP Socket发送和接收的数据报

在这里插入图片描述
第一个方法,不需要设置地址进去,通常用来接受消息
第二个方法,需要显式的设置地址进去,通常用来发送消息

下面基于UDP socket写一个最简单客户端服务器程序(回显服务器 echo server)
一个服务器,主要做三个核心工作
1.读取请求
2.根据请求计算响应
3.把响应返回客户端

UDP的回显服务器

代码示例:

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPEchoServer {
    private static final int BUFFER_SIZE = 1024;
    private static final int PORT = 8888;

    public static void main(String[] args) {
        try {
            DatagramSocket serverSocket = new DatagramSocket(PORT);
            System.out.println("UDP Echo Server is running on port " + PORT);

            byte[] receiveBuffer = new byte[BUFFER_SIZE];

            while (true) {
                DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
                serverSocket.receive(receivePacket);

                String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
                System.out.println("Received from client: " + message);

                // 构造回复数据报
                DatagramPacket sendPacket = new DatagramPacket(receivePacket.getData(), receivePacket.getLength(),
                        receivePacket.getAddress(), receivePacket.getPort());
                serverSocket.send(sendPacket);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

UDP的回显服务器的执行顺序

  1. 服务器先启动,执行到receive进行阻塞

  2. 客户端运行之后,从控制台读取数据,并进行send

  3. 客户端这边,send之后,继续往下走,走到receive读取响应
    服务器这边,是从receive返回,读取请求数据(客户端发来的),往下走到 process生成响应,再往下走到send,并且打印日志

  4. 客户端这边真正收到服务器send回来的数据后,就会解除阻塞,执行下面的打印操作
    服务器这边进入下一个循环,再次阻塞在receive,等待客户端下一个请求

  5. 客户端继续进行下一轮循环,阻塞在Scanner.next这里,等待用户输入新的数据

流程:
客户端:
1.读取用户输入
2.构造请求,并发送

服务器
3.读取用户的请求数据
4.根据要求计算响应
5.把响应写回到客户端

客户端
6.客户端读取服务器的响应
7.客户端把响应转成字符串,并显示出来

服务器是一个进程,客户端是一个进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值