UDP简单总结

news2024/11/24 6:34:33

UDP:用户数据报协议

  • 特点: 无连接、不可靠通信

  • 不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口、目的地IP、程序端口和数据(限制在64KB内)

  • 发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故不可靠

  • Java代码常用方法
    • DatagramSocket():创建一个未绑定到任何本地地址和端口的DatagramSocket对象。
      DatagramSocket socket = new DatagramSocket();
      
    • DatagramSocket(int port):创建一个绑定到指定端口的DatagramSocket对象。
      DatagramSocket socket = new DatagramSocket(8080);
      
    • send(DatagramPacket packet):发送数据报包。
      byte[] data = "Hello, world!".getBytes();
      DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 8080);
      socket.send(packet);
      
    • receive(DatagramPacket packet):接收数据报包。
      byte[] buffer = new byte[1024];
      DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
      socket.receive(packet);
      
    • setSoTimeout(int timeout):设置接收超时时间(以毫秒为单位)。
      socket.setSoTimeout(5000); // 设置5秒超时
    • close():关闭套接字。
      socket.close();
      
    • bind(SocketAddress bindaddr):将套接字绑定到特定的本地地址和端口。
      socket.bind(new InetSocketAddress("localhost", 8080));
    • getLocalSocketAddress():获取套接字绑定的本地地址和端口。
      SocketAddress localAddress = socket.getLocalSocketAddress();
      

 下面是一个简单的示例代码,演示如何使用DatagramSocket发送和接收UDP数据报:

import java.net.*;

public class UDPSocketExample {
    public static void main(String[] args) {
        try {
            // 创建一个DatagramSocket对象并绑定到本地端口8080
            DatagramSocket socket = new DatagramSocket(8080);

            // 准备发送的消息字符串
            String message = "Hello, UDP!";
            
            // 将消息字符串转换为字节数组
            byte[] sendData = message.getBytes();
            
            // 获取接收者的地址(本地主机)和端口号(8081)
            InetAddress receiverAddress = InetAddress.getByName("localhost");
            int receiverPort = 8081;

            // 创建一个DatagramPacket对象,用于发送数据
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receiverAddress, receiverPort);
            
            // 发送数据报包
            socket.send(sendPacket);
            System.out.println("Sent message: " + message);

            // 创建一个字节数组用于接收数据
            byte[] receiveData = new byte[1024];
            
            // 创建一个DatagramPacket对象,用于接收数据
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            
            // 接收数据报包
            socket.receive(receivePacket);
            
            // 从接收的数据报包中获取消息字符串
            String receivedMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("Received message: " + receivedMessage);

            // 关闭套接字
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

        在此示例中,我们使用DatagramSocket实现了一个简单的UDP通信程序。首先,我们创建了一个DatagramSocket对象并绑定到本地端口8080。然后,我们准备了要发送的消息字符串,并将其转换为字节数组。接着,我们获取了接收者的地址(本地主机)和端口号(8081),并创建了一个DatagramPacket对象用于发送数据。我们发送了数据报包,并在控制台打印了发送的消息。接着,我们创建了一个用于接收数据的字节数组和DatagramPacket对象,并接收了从本地端口8081发送的数据报包。最后,我们从接收的数据报包中获取消息字符串,并在控制台打印接收到的消息。最后,我们关闭了套接字。

        当然这只是实现了单发单收,我们可以利用死循环实现一个客户端和一个服务端的多发多收。下面我们利用线程实现多发多收。

下面是一个示例代码,演示如何实现多发多收的UDP通信:

import java.net.*;

public class MultiSendReceiveUDP {
    public static void main(String[] args) {
        try {
            // 创建DatagramSocket对象并绑定到本地端口8080
            DatagramSocket socket = new DatagramSocket(8080);

            // 启动接收线程
            Thread receiverThread = new Thread(new Receiver(socket));
            receiverThread.start();

            // 创建发送者线程并启动
            Thread sender1 = new Thread(new Sender(socket, "Message 1", "localhost", 8081));
            Thread sender2 = new Thread(new Sender(socket, "Message 2", "localhost", 8081));
            sender1.start();
            sender2.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 接收者线程类
    static class Receiver implements Runnable {
        private DatagramSocket socket;

        public Receiver(DatagramSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                // 创建一个字节数组用于接收数据
                byte[] receiveData = new byte[1024];

                while (true) {
                    // 创建一个DatagramPacket对象,用于接收数据
                    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                    
                    // 接收数据报包
                    socket.receive(receivePacket);

                    // 从接收的数据报包中获取消息字符串
                    String receivedMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
                    System.out.println("Received message: " + receivedMessage);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 发送者线程类
    static class Sender implements Runnable {
        private DatagramSocket socket;
        private String message;
        private String receiverHost;
        private int receiverPort;

        public Sender(DatagramSocket socket, String message, String receiverHost, int receiverPort) {
            this.socket = socket;
            this.message = message;
            this.receiverHost = receiverHost;
            this.receiverPort = receiverPort;
        }

        @Override
        public void run() {
            try {
                // 将消息字符串转换为字节数组
                byte[] sendData = message.getBytes();
                
                // 获取接收者的地址和端口号
                InetAddress receiverAddress = InetAddress.getByName(receiverHost);

                // 创建一个DatagramPacket对象,用于发送数据
                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receiverAddress, receiverPort);
                
                // 发送数据报包
                socket.send(sendPacket);
                System.out.println("Sent message: " + message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

        在此示例中,我们创建了一个MultiSendReceiveUDP类,其中包含了main方法,以及ReceiverSender类,分别用于接收和发送数据。在main方法中,我们创建了一个DatagramSocket对象并绑定到本地端口8080,并启动了一个接收者线程。然后,我们创建了两个发送者线程,并将它们分别启动。每个发送者线程将向本地主机的端口8081发送一条消息。接收者线程将一直接收来自发送者的消息,并在控制台打印出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1581370.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用友NC Cloud importhttpscer接口存在任意文件上传漏洞

声明: 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 简介 用友NC Cloud 是基于云计算技术的企业管理软件。它提…

监控指标体系:交互延迟上的探索与最佳实践

FID 在互联网高速发展的时代,用户体验已成为企业竞争的关键所在。网页性能作为用户体验的重要组成部分,直接影响着用户的满意度和工作效率。First Input Delay(FID)作为衡量网页性能的重要指标,越来越受到业界关注。今天,让我们一起来深入了解FID,探讨如何优化FID以提升…

GitHub 仓库 (repository) Pulse - Contributors - Network

GitHub 仓库 [repository] Pulse - Contributors - Network 1. Pulse2. Contributors3. NetworkReferences 1. Pulse 显示该仓库最近的活动信息。该仓库中的软件是无人问津,还是在火热地开发之中,从这里可以一目了然。 2. Contributors 显示对该仓库进…

51单片机之LED点阵屏

目录 1.LED点阵屏简介 2.配置LED点阵屏代码 1.LED点阵屏简介 LED点阵屏真的是遍布我们我们生活的每个角落,从街边的流动显示字的招牌到你的液晶显示屏,都是基于点阵屏的原理研究出来的。还有那个世界上最大的球状建筑物:MSG Sphere&#xff…

签名失败当前系统没有安装苹果根证书

发生背景 第一次我没有iOS证书(.p12)和描述文件(.mobileprovision)。按照这个文档https://ask.dcloud.net.cn/article/152拿到后,安心打包出问题。 错误信息 [Info] begin getCertCName... [Info] begin codesignFramwork to ipa... [Error] DCUniBase.framework…

Mac 安装 brew brew cask 遇到的问题以及解决办法

安装Homebrew和Homebrew Cask是在Mac上管理软件包的常用方法。虽然大多数情况下安装这两个工具是比较简单的,但有时候也可能遇到一些问题。下面是一些常见的问题以及解决办法: 问题1:无法安装Homebrew 解决办法: 1.确保你的Mac已连…

跟TED演讲学英文:Why AI will spark exponential economic growth by Cathie Wood

TED英文文稿 文章目录 TED英文文稿Why AI will spark exponential economic growthIntroductionVocabularyTranscriptSummary Why AI will spark exponential economic growth Link: https://www.ted.com/talks/cathie_wood_why_ai_will_spark_exponential_economic_growth? …

打印CSDN博客只需两步

打印博客 关闭浏览器限制 浏览器打开对应博客&#xff0c;F12&#xff0c;在console下粘贴如下代码&#xff0c;回车 (function doPrint(){var head_str "<html><head><title></title></head><body>"; var foot_str "&…

three.js跟着教程实现VR效果(四)

参照教程&#xff1a;https://juejin.cn/post/6973865268426571784&#xff08;作者&#xff1a;大帅老猿&#xff09; 1.WebGD3D引擎 用three.js &#xff08;1&#xff09;使用立方体6面图 camera放到 立方体的中间 like “回” 让贴图向内翻转 &#xff08;2&#xff09;使…

【机器学习—聚类】

文章目录 1、前言1.1、定义1.2、数据 2、亲和力传播3、聚合聚类4、BIRCH5、DBSCAN6、K-均值7、Mini-Batch K-均值8、均值漂移聚类9、OPTICS10、光谱聚类11、高斯混合模型12、参考 1、前言 1.1、定义 聚类分析&#xff0c;即聚类&#xff0c;是一项无监督的机器学习任务。它包…

本地开发nginx代理服务器

1、nginx 解释 nginx 是一个高性能的HTTP和反向代理服务器&#xff0c;同时也是一个IMAP/POP3/SMTP 代理服务器。 在性能上&#xff0c;Nginx占用很少的系统资源&#xff0c;能支持更多的并发连接&#xff0c;达到更高的访问效率&#xff1b; 在功能上&#xff0c;Nginx是优…

番茄 abogus rpc调用

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章…

SpringMVC:搭建第一个web项目并配置视图解析器

&#x1f449;需求&#xff1a;用spring mvc框架搭建web项目&#xff0c;通过配置视图解析器达到jsp页面不得直接访问&#xff0c;实现基本的输出“hello world”功能。&#x1f469;‍&#x1f4bb;&#x1f469;‍&#x1f4bb;&#x1f469;‍&#x1f4bb; 1 创建web项目 1…

web安全学习笔记【22】——文件上传(1)

WEB攻防-PHP应用&文件上传&函数缺陷&条件竞争&二次渲染&黑白名单&JS绕过 演示案例&#xff1a; PHP-原生态-文件上传-前后端验证PHP-原生态-文件上传-类型文件头验证PHP-原生态-文件上传-后缀黑白名单验证PHP-原生态-文件上传-解析配置&二次渲染…

网页布局与样式设计:从简单到复杂

✨✨祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目录 引言 一. 基础布局技巧 1.使用CSS Grid布局设计网页布局 1.1 创建网格容器 1.2. 定义…

GridView控件的使用(一)

GridView控件通常用于在Windows窗体或Web应用程序中显示数据表格。它是一个强大的数据绑定控件&#xff0c;能够灵活地显示和编辑数据源中的数据。 在何种情况下应使用GridView进行绑定控件&#xff1a; 显示结构化数据&#xff1a;当您需要展示一系列具有相同字段的数据记录…

Go语言中的互斥锁(Mutex)和读写锁(RWMutex)

Mutex Mutex结构体 type Mutex struct {state int32 //表示互斥锁的状态,比如是否被锁定等sema uint32 //表示信号里,协程阻塞等待的信号量,解锁的协程释放信号量从而唤醒等待信号量的协程 } Locked: 表示Mutex是否已被锁定(1表示已经被锁定)Woken: 表示是否有协程被唤醒(1已有…

【JVM】面试题汇总

JVM1. 什么是JVM&#xff1f;2. 了解过字节码文件的组成吗&#xff1f;3. 什么是运行时数据区4. 哪些区域会出现内存溢出5. JVM在JDK6-8之间在内存区域上有什么不同 6. 类的生命周期 7. 什么是类加载器&#xff1f;类加载器有哪几种 8. 什么是双亲委派机制&#xff1f;有什么好…

HJ43 迷宫问题(动态规划,从(0,0)开始,四个方向遍历,深度优先搜索,找到一条路径。)

从&#xff08;0&#xff0c;0&#xff09;开始&#xff0c;四个方向遍历&#xff0c;深度优先搜索&#xff0c;找到一条路径。 import java.util.Scanner; import java.util.ArrayList;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public stati…

网络基础三——IP协议补充和Mac帧协议

全球网络及网段划分的理解 ​ 根据国家组织地区人口综合评估进行IP地址范围的划分&#xff1b; ​ 假设前8位用来区分不同的国家&#xff0c;国际路由器负责全球数据传输&#xff0c;子网掩码为IP/8&#xff1b;次6位区分不同的省份&#xff0c;国内路由器负责全国数据的传输…