UDP简单总结

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对象并绑定到本地端口8080DatagramSocket 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对象并绑定到本地端口8080DatagramSocket 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;}@Overridepublic 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;}@Overridepublic 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.mzph.cn/news/812559.shtml

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

相关文章

SpringBoot与MyBatisPlus的依赖版本冲突问题

记录使用SpringBoot和MyBatisPlus时遇到的版本冲突问题解决。 java版本:jdk17 废话:)目前在IDEA中使用Spring官方的脚手架最低jdk版本竟然是jdk17了。 当使用SpringBoot3.0版本(3.2.4),配合使用MP3.5.2版本时报错: Er…

对于所有对象都通用的方法⭐良好习惯总结

对于所有对象都通用的方法⭐良好习惯总结 Object是每个类的父类,它提供一些非final方法:equals、hashCode、clone、toString、finalize... 这些方法在设计上是可以被子类重写的,但是重写前需要遵守相关的规定,否则在使用时就可能…

应用实战|从头开始开发记账本2:基于模板快速开始

上期视频我们创建好了BaaS服务的后端应用。从这期视频开始,我们将从头开发一个互联网记账本应用。本期视频我们介绍一下如何使用模板快速开启我们的应用开发之旅。 应用实战|从头开始开发记账本2:基于模板快速开始 相关代码 本期视频我们介绍…

RestTemplate—微服务远程调用—案例解析

简介:总结来说,微服务之间的调用方式有多种,选择哪种方式取决于具体的业务需求、技术栈和架构设计。RESTful API和HTTP客户端是常见的选择,而Feign和Ribbon等辅助库可以简化调用过程。RPC和消息队列适用于特定的场景,如…

《由浅入深学习SAP财务》:第2章 总账模块 - 2.6 定期处理 - 2.6.4 月末操作:货币折算

2.6.4 月末操作:货币折算 如果一个公司代码启用了多个本位币,如下表所示,则在平时记账时,系统会在凭证行项目中同时体现出多个本位币的金额。 图2.6.4-1 两个本位币的金额都会实时更新到科目余额中。因此,在月末可以直…

pycharm2024关闭项目后一直显示正在关闭项目

网上的很多教程都试了不行,直接用下面的方法有效解决。 点击 帮助--查找操作--输入Registry--点注册表,取消ide.await.scope.completion后的勾选即可。

武汉星起航:跨境电商势头强劲,开启外贸增长新纪元

在全球化浪潮的推动下,跨境电商作为新兴贸易方式,正以前所未有的速度崛起。2024年前两个月,跨境电商进出口增长近10%,这一令人瞩目的数据,不仅彰显出跨境电商的强劲发展势头,更预示着其作为外贸新增长极的潜…

直接扩展到无限长,谷歌Infini-Transformer终结上下文长度之争

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 不知 Gemini 1.5 Pro 是否用到了这项技术。 谷歌又放大招了,发布下一代 Transfor…

突破像素限制,尽显照片细腻之美——Topaz Gigapixel AI for Mac/Win

在这个数字化的时代,我们都热爱用照片记录生活中的美好瞬间。然而,有时候我们会发现,由于各种原因,照片的像素可能无法满足我们的需求。这时候,Topaz Gigapixel AI for Mac/Win 这款强大的照片放大工具应运而生。 Top…

联储降息预期落空打了谁的脸

美国 3 月消费者价格指数(CPI)于本周发布,最新数据全线高于预期。具体而言,美国劳工部周三公布的数据显示,美国 3 月消费者物价指数(CPI)同比上涨 3.5%,为 2023 年 9 月以来最高水平…

python基础——类【类的定义和使用、魔术方法】

📝前言: python中的类,自我感觉在某种程度上和C语言的结构体是有共同之处的,如果有兴趣,可以先看看这篇文章:C语言——结构体类型(一),先了解一下C语言中的结构体&#x…

在Ubuntu上安装Docker Compose

Docker Compose 是一个用于定义和管理Docker容器的工具,它使用yml来配置应用的服务、网络和卷等。特别是在定义多个容器时,它非常擅长定义多个容器之间的关系和依赖。 第一步:更新软件包 sudo apt update第二步:安装网络工具cur…

基于FMC接口的Kintex-7 XC7K325T PCIeX4 3U PXIe接口卡

基于FMC接口的Kintex-7 XC7K325T PCIeX4 3U PXIe接口卡 一、板卡概述 本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持PCIeX8、64bit DDR3容量2GByte,HPC的FMC连接器,板卡支持PXI…

【INNODB引擎篇】深奥探究Innodb存储引擎

🔥作者主页:小林同学的学习笔录 🔥mysql专栏:小林同学的专栏 目录 1.InnoDB引擎 1.1 逻辑存储结构 1.2 架构 1.2.1 概述 1.2.2 内存结构 1.2.3 磁盘结构 1.2.4 后台线程 1.3 事务原理 1.3.1 事务基础 1.3.2 redo log 1.…

时间复杂度详解1——定义和简单计算

算法效率的度量方法 事后统计方法 事后统计方法:这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。 但这种方法显然是有很大缺陷的: 必须依据算法事先…

分布式系统:缓存与数据库一致性问题

前言 缓存设计是应用系统设计中重要的一环,是通过空间换取时间的一种策略,达到高性能访问数据的目的;但是缓存的数据并不是时刻存在内存中,当数据发生变化时,如何与数据库中的数据保持一致,以满足业务系统…

02-攻防世界PHP2

题目 authenticate:证明什么是真的 解题 观察题目可知,访问index.phps可能会有不一样的发现 http://61.147.171.105:51671/index.phps访问该链接,可以得到下面的界面 这里只显示出了部分代码,右键该界面,点击查看源代码&#xf…

使用ArrayList.removeAll(List list)导致的机器重启

背景 先说一下背景,博主所在的业务组有一个核心系统,需要同步两个不同数据源给过来的数据到redis中,但是每次同步之前需要过滤掉一部分数据,只存储剩下的数据。每次同步的数据与需要过滤掉的数据量级大概在0-100w的数据不等。 由…

【学习】移动端兼容性测试有什么方法及重要性

随着移动互联网的快速发展,移动应用程序已经成为人们日常生活中不可或缺的一部分。然而,由于各种移动设备的硬件和软件差异,移动应用程序的兼容性问题也越来越突出。因此,移动端兼容性测试成为了一个重要的环节,它可以…

如何在 Android 设备上恢复已删除/丢失的文档

随着Android设备内存容量的不断增加,许多人将手机作为移动硬盘来存储大量文档或其他文件。由于某些原因,文件丢失绝对是一场彻头彻尾的噩梦,因为里面的数据可能是要汇报的学习档案、领导会议的安排、或者付费电子书等。通常,你首先…