本文主要是介绍【愚公系列】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有三种通讯方式,分别是单播、广播和组播。
-
单播(Unicast):一对一通讯方式,即一个发送端发送数据包到一个接收端。
-
广播(Broadcast):一对多通讯方式,即一个发送端发送数据包到所有在同一网络中的接收端。
-
组播(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协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!