【愚公系列】2023年10月 Java教学课程 078-网络编程UDP协议

2023-10-31 09:30

本文主要是介绍【愚公系列】2023年10月 Java教学课程 078-网络编程UDP协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

文章目录

  • 🚀一.UDP协议
    • 🔎1.UDP发送数据
    • 🔎2.UDP接收数据
    • 🔎3.UDP通信案例
    • 🔎4.UDP三种通讯方式
      • 🦋4.1 UDP组播实现
      • 🦋4.2 UDP广播实现
  • 🚀感谢:给读者的一封信


🚀一.UDP协议

UDP(User Datagram Protocol,用户数据报协议)是一种无连接协议,它提供了不可靠的数据传输服务。UDP协议没有数据重传和数据包状态确认机制,数据包发送出去后就无法保证是否能够被接收方正确接收。

尽管UDP在可靠性和可控性方面不如TCP,但其速度更快,开销更小,因此它在某些应用场景中更加适用,如视频、音频的实时传输、在线游戏等。

🔎1.UDP发送数据

方法名描述示例
DatagramPacket(byte[] buf, int length, InetAddress address, int port)构造UDP数据包byte[] data = “Hello World”.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(“localhost”), 8888);
DatagramSocket()构造UDP套接字DatagramSocket socket = new DatagramSocket();
send(DatagramPacket packet)发送UDP数据包byte[] data = “Hello World”.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(“localhost”), 8888);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
receive(DatagramPacket packet)接收UDP数据包byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
DatagramSocket socket = new DatagramSocket(8888);
socket.receive(packet);
setSoTimeout(int timeout)设置套接字超时时间DatagramSocket socket = new DatagramSocket(8888);
socket.setSoTimeout(5000);

示例:

import java.net.*;public class UDPSender {public static void main(String[] args) {try {// 创建数据报byte[] data = "Hello World".getBytes();DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 8888);// 创建套接字DatagramSocket socket = new DatagramSocket();// 发送数据报socket.send(packet);System.out.println("数据发送完毕");// 关闭套接字socket.close();} catch (Exception e) {e.printStackTrace();}}
}import java.net.*;public class UDPReceiver {public static void main(String[] args) {try {// 创建数据报byte[] buffer = new byte[1024];DatagramPacket packet = new DatagramPacket(buffer, buffer.length);// 创建套接字DatagramSocket socket = new DatagramSocket(8888);// 接收数据报socket.receive(packet);System.out.println("接收到数据:" + new String(packet.getData(), 0, packet.getLength()));// 关闭套接字socket.close();} catch (Exception e) {e.printStackTrace();}}
}

🔎2.UDP接收数据

方法名返回类型描述示例
DatagramSocket(int port)DatagramSocket创建一个新的DatagramSocket对象,使用指定的本地端口DatagramSocket socket = new DatagramSocket(9999);
DatagramPacket(byte[] buf, int length)DatagramPacket创建一个DatagramPacket对象,用于接收数据byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
receive(DatagramPacket p)void接收数据报文socket.receive(packet);
getData()byte[]获取数据报文的字节数组byte[] data = packet.getData();
getLength()int获取数据报文的长度int length = packet.getLength();
getAddress()InetAddress获取数据报文的发送方地址InetAddress address = packet.getAddress();
getPort()int获取数据报文的发送方端口号int port = packet.getPort();

示例代码:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class UDPServer {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket(9999);byte[] buf = new byte[1024];DatagramPacket packet = new DatagramPacket(buf, buf.length);socket.receive(packet);String data = new String(packet.getData(), 0, packet.getLength());InetAddress address = packet.getAddress();int port = packet.getPort();System.out.println("接收到数据:" + data + ",来自:" + address + ":" + port);socket.close();}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class UDPClient {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket();String data = "Hello, UDP Server!";byte[] buf = data.getBytes();DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 9999);socket.send(packet);socket.close();}
}

🔎3.UDP通信案例

以下是一个使用UDP进行实际通信的聊天程序,用户可以向其他用户发送消息。

服务器端代码:

import java.net.*;public class UDPServer {public static void main(String[] args) throws Exception {DatagramSocket serverSocket = new DatagramSocket(9876);System.out.println("Server is running on port 9876.\n");byte[] receiveData = new byte[1024];byte[] sendData = new byte[1024];while(true) {DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);serverSocket.receive(receivePacket);String message = new String(receivePacket.getData()).trim();System.out.println("\nReceived message from client: " + message);InetAddress IPAddress = receivePacket.getAddress();int port = receivePacket.getPort();String[] messageArray = message.split(" ");String messageType = messageArray[0];String senderName = messageArray[1];String messageText = "";if(messageArray.length > 2) {for(int i=2; i<messageArray.length; i++) {messageText += messageArray[i] + " ";}}String response = "";if(messageType.equals("JOIN")) {response = "Server: " + senderName + " has joined the chat.";} else if(messageType.equals("MESSAGE")) {response = senderName + ": " + messageText;} else if(messageType.equals("LEAVE")) {response = "Server: " + senderName + " has left the chat.";}sendData = response.getBytes();DatagramPacket sendPacket =new DatagramPacket(sendData, sendData.length, IPAddress, port);serverSocket.send(sendPacket);}}
}

客户端代码:

import java.net.*;public class UDPClient {public static void main(String[] args) throws Exception {InetAddress IPAddress = InetAddress.getLocalHost();DatagramSocket clientSocket = new DatagramSocket();System.out.println("Welcome to the chat room!\n");while(true) {String message = getMessageFromUser();byte[] sendData = new byte[1024];byte[] receiveData = new byte[1024];sendData = message.getBytes();DatagramPacket sendPacket =new DatagramPacket(sendData, sendData.length, IPAddress, 9876);clientSocket.send(sendPacket);if(message.equals("LEAVE")) {break;}DatagramPacket receivePacket =new DatagramPacket(receiveData, receiveData.length);clientSocket.receive(receivePacket);String response = new String(receivePacket.getData()).trim();System.out.println("\n" + response);}clientSocket.close();}public static String getMessageFromUser() {String message = "";System.out.print("Enter message (JOIN, MESSAGE, or LEAVE): ");try {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));message = br.readLine();if(message.equals("MESSAGE")) {System.out.print("Enter message text: ");message += " " + br.readLine();} else if(message.equals("JOIN")) {System.out.print("Enter your name: ");message += " " + br.readLine();} else if(message.equals("LEAVE")) {System.out.print("Are you sure you want to leave? (Y/N): ");String answer = br.readLine();if(answer.equals("Y")) {System.out.println("Goodbye!");} else {message = getMessageFromUser();}} else {System.out.println("Invalid message type. Please try again.\n");message = getMessageFromUser();}} catch(Exception e) {System.out.println("Error: " + e.getMessage());System.exit(0);}return message;}
}

在这个案例中,客户端输入JOIN加上自己的名字来加入聊天室,输入MESSAGE加上要发送的消息文本来发送消息,输入LEAVE来离开聊天室。客户端会将这些消息转换为字符串并发送到服务器。服务器将消息解析,并返回相应的响应消息。客户端会在控制台上显示这些响应消息。

实际上,UDP还可以用于实现各种游戏和实时应用程序,因为它可以实现快速而精细的数据传输。

🔎4.UDP三种通讯方式

UDP(User Datagram Protocol)是一种无连接的、无状态的通信协议,主要用于快速传输小数据包,不保证数据的可靠性和顺序。UDP有三种通讯方式,分别是单播、广播和组播。

  1. 单播(Unicast):一对一通讯方式,即一个发送端发送数据包到一个接收端。

  2. 广播(Broadcast):一对多通讯方式,即一个发送端发送数据包到所有在同一网络中的接收端。

  3. 组播(Multicast):多对多通讯方式,即一个发送端向一个多播组发送数据包,并且只有加入该组的接收端才能接收到数据包。组播需要设定特殊的IP地址范围,例如224.0.0.0 - 239.255.255.255是保留的组播地址范围。

🦋4.1 UDP组播实现

UDP组播是一种UDP数据包的传输方式,它通过一个组播地址将数据包发送给多个接收方,而不是单个目的地。Java中的UDP组播使用的是MulticastSocket类。

原理:

UDP组播是基于IP多播实现的。在IP多播中,一个数据报被发送到一个专门的IP地址,该地址被指定为多个接收方的标识符。在网络上,多个接收方共享同一个IP地址,同时使用不同的端口号进行通信。当数据包被发送到多播地址时,路由器会将数据包复制并传递到所有连接到该地址的接收方。

Java中的UDP组播示例:

以下是一个简单的Java UDP组播示例,其中客户端和服务器端通过组播地址进行通信。

服务端:

import java.net.*;public class MulticastServer {public static void main(String[] args) throws Exception {MulticastSocket serverSocket = new MulticastSocket();String message = "Hello, World!";InetAddress group = InetAddress.getByName("224.0.0.1"); // 组播地址DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), group, 1234);serverSocket.send(packet);serverSocket.close();}
}

客户端:

import java.net.*;public class MulticastClient {public static void main(String[] args) throws Exception {MulticastSocket clientSocket = new MulticastSocket(1234);InetAddress group = InetAddress.getByName("224.0.0.1"); // 组播地址clientSocket.joinGroup(group);byte[] buffer = new byte[1024];DatagramPacket packet = new DatagramPacket(buffer, buffer.length);clientSocket.receive(packet);String message = new String(packet.getData(), 0, packet.getLength());System.out.println("Received message: " + message);clientSocket.leaveGroup(group);clientSocket.close();}
}

服务端使用MulticastSocket类创建一个UDP套接字,并将数据包发送到组播地址224.0.0.1。客户端也使用MulticastSocket类创建一个UDP套接字,并加入到与服务端相同的组播地址。客户端接收到数据包后,打印消息并离开组播组。

🦋4.2 UDP广播实现

UDP广播是一种发送和接收UDP数据报的广播形式,UDP广播使用IP地址 255.255.255.255 或某个特定的广播地址。在局域网中,所有与该网络连通的主机都会接收到UDP广播数据包。

import java.net.*;public class UDPBroadcastSender {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket();socket.setBroadcast(true);byte[] buffer = "This is a UDP broadcast message".getBytes();DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("255.255.255.255"), 8888);socket.send(packet);System.out.println("UDP broadcast message sent");socket.close();}
}

我们首先创建了一个DatagramSocket对象,并将其设置为支持广播。然后,我们使用BufferedWriter将要发送的消息转换为字节数组,并创建一个DatagramPacket对象,该对象包含了要发送的数据、目标地址和端口号。最后,我们通过调用DatagramSocket的send()方法来发送UDP广播消息。

UDP广播消息的示例代码:

import java.net.*;public class UDPBroadcastReceiver {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket(8888);socket.setBroadcast(true);byte[] buffer = new byte[1024];DatagramPacket packet = new DatagramPacket(buffer, buffer.length);while (true) {socket.receive(packet);String message = new String(packet.getData(), 0, packet.getLength());System.out.println("UDP broadcast message received: " + message);}}
}

我们创建了一个DatagramSocket对象并绑定到8888端口,然后将其设置为支持广播。接着,我们创建一个字节数组和一个DatagramPacket对象,并在while循环中使用DatagramSocket的receive()方法来接收UDP广播消息。当消息到来时,我们将其转换为字符串并打印到控制台上。


🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

在这里插入图片描述

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

这篇关于【愚公系列】2023年10月 Java教学课程 078-网络编程UDP协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/314377

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor