Java的UDP通信
UDP发送数据
-
Java中的UDP通信
- UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
- Java提供了DatagramSocket类作为基于UDP协议的Socket
-
构造方法
方法名 说明 DatagramSocket() 创建数据报套接字并将其绑定到本机地址上的任何可用端口 DatagramPacket(byte[] buf,int len,InetAddress add,int port) 创建数据包,发送长度为len的数据包到指定主机的指定端口 -
相关方法
方法名 说明 void send(DatagramPacket p) 发送数据报包 void close() 关闭数据报套接字 void receive(DatagramPacket p) 从此套接字接受数据报包
-
发送数据的步骤,我们也可以把发送数据的步骤理解为给自己心爱的女神发送快递的全过程
- 寻找快递公司(创建发送端的Socket对象(DatagramSocket))
- 打包快递(创建数据,并把数据打包)
- 快递发货(调用DatagramSocket对象的方法发送数据)
- 付钱走人(关闭发送端)
-
代码演示
package net; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; public class SendMessageDemo1 { public static void main(String[] args) throws IOException { //1.创建DatagramSocket对象(快递公司) //细节 //绑定端口:以后我们就是通过这个端口发送数据 //有参:指定端口号进行绑定 //无参:在所有可用端口中随机绑定一个端口 DatagramSocket ds = new DatagramSocket(); //2.打包快递,打包数据 Scanner sc = new Scanner(System.in); while (true) { System.out.println("请输入要发送的数据:"); String str = sc.nextLine(); if ("000".equals(str)) { break; } byte[] bytes = str.getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 10086; DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port); //3.快递发货,发送数据 ds.send(dp); } //4.付钱走人,释放资源 ds.close(); } }
UDP接收数据
-
接收数据的步骤可以理解为女神收到我们快递的过程
- 找到快递驿站(创建接收端的Socket对象(
DatagramSocket
)) - 找到快递(创建一个数据包,用于接收数据)
- 签收快递(调用DatagramSocket对象的方法接收数据)
- 拆开快递(解析数据包,并把数据在控制台显示)
- 最后发现我们送到礼物女神不喜欢,把我们拉黑(关闭接收端)
- 找到快递驿站(创建接收端的Socket对象(
-
构造方法
方法名 说明 DatagramPacket(byte[] buf, int len) 创建一个DatagramPacket用于接收长度为len的数据包 -
相关方法
方法名 说明 byte[] getData() 返回数据缓冲区 int getLength() 返回要发送的数据的长度或接收的数据的长度 -
示例代码
package net; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class ReceiveMessageDemo1 { public static void main(String[] args) throws Exception { //1.创建DatagramSocket对象(快递公司) //细节: //在接收的时候,一定要绑定端口 //而且绑定的端口一定要跟发送的端口保持一致 DatagramSocket ds = new DatagramSocket(10086); //2.接受数据包 byte[] bytes = new byte[1024]; DatagramPacket dp = new DatagramPacket(bytes, bytes.length); while (true) { //该方法是阻塞的 //程序执行到这一步的时候,会在这里一直等 //等发送端发送消息 ds.receive(dp); //3.解析数据包 byte[] data = dp.getData(); InetAddress address = dp.getAddress(); int length = dp.getLength(); System.out.println("接收到数据" + new String(data, 0, length)); System.out.println("来自" + address + ":" + dp.getPort()); } } }
UDP三种通讯方式
- 单播
单播用于两个主机之间的端对端通信,使用DatagramSocket
简易版数据的发送与接收就是单播
-
组播
组播用于对一组特定的主机进行通信
组播地址:224.0.0.0-239.255.255.255
其中224.0.0.0-224.0.0.255为预留的组播地址
-
广播
广播用于一个主机对整个局域网上所有主机上的数据通信
组播地址:255.255.255.255
UDP组播实现
-
实现步骤
- 发送端
- 创建发送端的Socket对象(DatagramSocket)
- 创建数据,并把数据打包(DatagramPacket)
- 调用DatagramSocket对象的方法发送数据(在单播中,这里是发给指定IP的电脑但是在组播当中,这里是发给组播地址)
- 释放资源
- 接收端
- 创建接收端Socket对象(MulticastSocket)
- 创建一个箱子,用于接收数据
- 把当前计算机绑定一个组播地址
- 将数据接收到箱子中
- 解析数据包,并打印数据
- 释放资源
- 发送端
-
代码实现
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class SendMessageDemo1 {
public static void main(String[] args) throws Exception {
/**
* 组播发送代码
*/
//1.创建MulticastSocket对象
MulticastSocket ms = new MulticastSocket();
//2.创建数据包,封装要发送的数据
byte[] bytes = "你好帅".getBytes();
InetAddress address = InetAddress.getByName("224.0.0.3");
int port = 10086;
//3.发送数据
ms.send(new DatagramPacket(bytes, bytes.length, address, port));
//4.释放资源
ms.close();
}
}
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class ReceiveMessageDemo1 {
public static void main(String[] args) throws Exception {
/**
* 组播接受代码
*/
//1.创建MulticastSocket对象
MulticastSocket ms = new MulticastSocket(10086);
//2.将当前本机添加到指定的组播地址224.0.0.3中
InetAddress address = InetAddress.getByName("224.0.0.3");
ms.joinGroup(address);
//3.创建DatagramPacket对象,用于接收数据
byte bytes[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
//4.接收数据
ms.receive(dp);
//5.解析数据
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress ip = dp.getAddress();
String name = dp.getAddress().getHostName();
System.out.println("来自" + name + ":" + ip + ":" + new String(data, 0, len));
//6.释放资源
ms.close();
}
}
UDP广播实现
-
实现步骤
- 发送端
- 创建发送端Socket对象(DatagramSocket)
- 创建存储数据的箱子,将广播地址封装进去
- 发送数据
- 释放资源
- 接收端
- 创建接收端的Socket对象(DatagramSocket)
- 创建一个数据包,用于接收数据
- 调用DatagramSocket对象的方法接收数据
- 解析数据包,并把数据在控制台显示
- 关闭接收端
- 发送端
-
代码实现
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class SendMessageDemo1 {
public static void main(String[] args) throws Exception {
/**
* 广播发送代码
*/
//1.创建MulticastSocket对象
MulticastSocket ms = new MulticastSocket();
//2.创建数据包,封装要发送的数据
byte[] bytes = "你好帅".getBytes();
InetAddress address = InetAddress.getByName("255.255.255.255");
int port = 10086;
//3.发送数据
ms.send(new DatagramPacket(bytes, bytes.length, address, port));
//4.释放资源
ms.close();
}
}
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class ReceiveMessageDemo1 {
public static void main(String[] args) throws Exception {
/**
* 广播接受代码
*/
//1.创建MulticastSocket对象
MulticastSocket ms = new MulticastSocket(10086);
//2.将当前本机添加到指定的组播地址224.0.0.3中
InetAddress address = InetAddress.getByName("224.0.0.3");
ms.joinGroup(address);
//3.创建DatagramPacket对象,用于接收数据
byte bytes[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
//4.接收数据
ms.receive(dp);
//5.解析数据
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress ip = dp.getAddress();
String name = dp.getAddress().getHostName();
System.out.println("来自" + name + ":" + ip + ":" + new String(data, 0, len));
//6.释放资源
ms.close();
}
}