没想到你是这样的UDP

简介: UDP是国际标准化组织为互联网设定的标准中的传输层中的一个协议。TCP/IP协议簇是一个很庞大的家族,但是今天我们就来看一看这个面向无连接的传输层在Java中是怎样通过编程实现的。

UDP是国际标准化组织为互联网设定的标准中的传输层中的一个协议。TCP/IP协议簇是一个很庞大的家族,但是今天我们就来看一看这个面向无连接的传输层在Java中是怎样通过编程实现的。


原理性知识

在Java中编写基于UDP协议的应用是最简单不过的了,我们只需要按照这几个特定的步骤就可以完成了。因为在Java中,已经将底层的协议信息全部封装了起来,对我们这些在应用层上的开发人员来说是透明的。通过API中给出的接口,我们可以轻松的开发出一款简单的小应用。

实现的流程

从逻辑上来说,如下图:
这里写图片描述

表现在代码上,可以这样做(因为是找的图,端口貌似不正确,请见谅):
这里写图片描述

编码实现一下:

我们先从客户端开始吧。

package tcp.udp;

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

public class Client {

    public static void main(String[] args) {
        try {
            //创建一个“发射器”,相当于快递员,将我们的“DatagramPacket”发和收
            DatagramSocket socket = new DatagramSocket();
            //一个字节数组,作为传输过程中的容器,将数据一个字节一个字节的发和收
            byte[] buf = "Hello Server ! I am Client!".getBytes();
            //我们的包裹,包含目的地和端口还有我们的数据
            DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 10000);
            //让快递员发出我们的包裹,剩下的事情,就交给底层来实现了
            socket.send(sendPacket);

            //创建一个我们将要接收的包裹
            DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
            //从快递员那里收到一个包裹。这个方法会阻塞哦。(也就是说,在特定的时间内没有收到包裹,我们会一直等下去。过期的话,才会离开,即不阻塞)
            socket.receive(receivePacket);
            //将接收到的字节转换成字符串,方便打印到控制台上
            String recvStr = new String(receivePacket.getData(), 0, receivePacket.getLength());
            //打印出接收到的数据信息
            System.out.println("服务器端传来的消息是: " + recvStr);

            //关闭套接字,快递员下班咯
            socket.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

下面轮到我们的服务器端了。

package tcp.udp;

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

public class Server {

    public static void main(String[] args) throws Exception {

        //快递员上班了,他在10000端口等着为我们服务
        DatagramSocket socket = new DatagramSocket(10000);

        //创建一个带缓冲的字节数组
        byte[] buf = new byte[1024];

        //创建一个具有一定容量的包裹
        DatagramPacket recvPacket = new DatagramPacket(buf, buf.length);
        //从快递公司(也就是我们的网络的底层)接收到我们的包裹
        socket.receive(recvPacket);
        //将接收到的数据转换成字符串,方便打印
        String recvStr = new String(recvPacket.getData(),0,recvPacket.getLength());
        //打印出接收到的数据
        System.out.println("收到的来自客户端的消息是: " + recvStr);

        //这里是我们想要发送的包裹的里面的内容。要一个字节一个字节的叠好(就像包裹内一个个的衣服一样)
        buf = "Hello Client,I am your server!".getBytes();
        //包裹一下,准备投递咯,我们可以从刚才的寄件人哪里找到发送的目的地和目的端口,也即是我们要回复的人的姓名和住址呗
        DatagramPacket sendPacket = new DatagramPacket(buf,buf.length,recvPacket.getAddress(),recvPacket.getPort());

        //让快递员帮我们投递包裹,发出包
        socket.send(sendPacket);
        //快递员下班了,套接字要进行关闭
        socket.close();
    }

}

注意事项

  • 对于服务器端和客户端:
    这里面没有什么特别的需要注意的。就是一些顺序问题。当然了,这里如果我们可以将这个案例附着到实际的生活中,很容易的就可以理解了。想象一下这样的场景,邮局不开门,你能投递包裹吗?不能吧,所以要想投递包裹,前提就是邮局开门,也就是服务器端要先运行。

  • 对于服务器端内部:
    还是这个想法,现在邮局想给我们转发信件,要是我们不知道目的地,我们该往哪里发?所以邮局必须要知道你要发送的目的地等详细信息。而这些在代码中,不正是要先收一下packet,才能找到这些信息的吗?所以,服务器端要先收包,然后才能发包。

  • 对于客户端内部:
    类比于服务器端内部,当然是对称着进行咯。我们发了他才能收嘛。所以对于客户端而言,正好和服务器端是镜像对称的,要先发后收packet。

总结与展望

对于这个案例,想必通过我这样一种通俗的解释你已经是理解了吧。但是对于UDP的开发而言,有很多的变种,在实际的开发过程中,有很多很多的不一样的实现方式。但是这里的理念永远不会过时滴,就放心的用吧。

对于UDP,我的下一个小案例,就是让服务器端和客户端互动起来,实现一个类似于“剪刀石头布”的小游戏。敬请期待哦。

目录
相关文章
|
前端开发
websocket的心跳机制
websocket的心跳机制
1649 3
|
存储 算法 Java
【JAVA】生成accessToken原理
在Java中,生成accessToken用于身份验证和授权,确保合法用户访问受保护资源。流程包括:1. 身份验证(如用户名密码、OAuth 2.0);2. 生成唯一且安全的令牌;3. 设置令牌有效期并存储;4. 客户端传递令牌,服务器验证其有效性。常见场景为OAuth 2.0协议,涉及客户端注册、用户授权、获取授权码和换取accessToken。示例代码展示了使用Apache HttpClient库模拟OAuth 2.0获取accessToken的过程。
|
存储 JavaScript 前端开发
Vue中组件通信方式有哪些?
本文介绍了 Vue 中几种常见的组件间通信方式,包括 Props / $emit、provide / inject、ref / refs、eventBus、Vuex、$parent / $children、$attrs / $listeners 以及通过 vue-router 传参。每种方式都有其适用场景和注意事项,帮助开发者根据具体需求选择合适的通信方式。
240 3
Vue中组件通信方式有哪些?
|
JSON 前端开发 安全
【潜意识java】前后端跨域问题及解决方案
本文深入探讨了跨域问题及其解决方案。跨域是指浏览器出于安全考虑,限制从一个域加载的网页请求另一个域的资源。
3387 0
|
弹性计算 固态存储 大数据
阿里云服务器多少钱一年?2024年7月最新租用价格表曝光!
阿里云2024年服务器租用费用更新,轻量应用服务器2核2G3M带宽年费82元,折合6.8元/月;2核4G5M带宽ECS优惠价199元/年。新老用户同享99元/年的2核2G经济型e实例,4核16G游戏服务器70元/月,8核32G服务器160元/月。GPU服务器gn6v、gn6i等最高配置月费4685.20元起。续费折扣根据时长,最长享3折优惠。按小时计费,如通用型u1-c1m4.large 0.45元/小时。带宽和云盘亦有多种计费选项。详情参见阿里云官网。
1024 4
|
编解码
MATLAB | SCI 绘图配色第三四期 | 二维堆叠柱状图 | 大理寺日志
MATLAB | SCI 绘图配色第三四期 | 二维堆叠柱状图 | 大理寺日志
468 0
|
XML IDE Java
REDHAWK——组件
REDHAWK——组件
267 0
|
存储 SpringCloudAlibaba 监控
系统高可用番外篇:浅析sentinel源码
Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从**限流、流量整形、熔断降级、系统负载保护、热点防护**等多个维度来帮助开发者保障微服务的稳定性。
538 0
系统高可用番外篇:浅析sentinel源码
|
开发工具 Android开发 开发者
Android平台GB28181接入端语音广播和语音对讲规范解读和技术实现
我在之前的blog,有提到过Android端GB28181接入端的语音广播和语音对讲,今天主要从GB/T28181-2016官方规范和交互流程,大概介绍下Android平GB28181接入端的语音广播和语音对讲。
573 0