Java Socket网络编程​(二)UDP通信及多播
  93byl95AX42O 2023年12月29日 16 0


UDP通信程序编写

发送数据

用发快递来做比喻,用UDP发送数据可以拆分为以下几个步骤:

Java Socket网络编程​(二)UDP通信及多播_java


需要使用DatagramSocket创建UDP连接,然后使用DatagramPacket打包要发送的数据,示例代码:

import java.io.IOException;
import java.net.*;

public class UDPSendingMsgDemo {
 public static void main(String[] args) throws IOException {
 // 发送数据

 //1.创建DatagramSocket对象(快递公司)
 // 细节:
 //绑定端口,以后我们就是通过这个端口往外发送
 // 空参:所有可用的端口中随机一个进行使用
 // 有参:指定端口号进行绑定
 DatagramSocket ds = new DatagramSocket();

 // 2.打包数据
 // 使用DatagramPacket类
 // 需要指定消息内容、消息大小、IP地址、端口号
 String str = "你好,世界"; // 要发送的消息
 byte[] bytes = str.getBytes(); // 转换为字节数组
 InetAddress address = InetAddress.getByName("127.0.0.1"); // 获取目的地IP地址对象
 int port = 10086; // 指定端口号
 // 创建UDP数据包对象
 DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);

 // 3.发送数据
 ds.send(dp);

 // 4.释放资源
 ds.close(); // 关闭连接
 }
}


接收数据

用收快递来比如,可以拆分为如下步骤:

Java Socket网络编程​(二)UDP通信及多播_数据_02


接收时也需要使用到DatagramSocket类和DatagramPacket类, 但是在接收时,DatagramSocket不需指定IP。代码如下:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPReceivingMsgDemo {
 public static void main(String[] args) throws IOException {
 // 接收数据

 //1.创建DatagramSocket对象(快递公司)
 // 细节:
 //在接收的时候,一定要绑定端口
 // 而且绑定的端口一定要跟发送的端口保持一致
 DatagramSocket ds = new DatagramSocket(10086);

 // 2.接收数据包
 byte[] bytes = new byte[1024]; // 创建用于接收数据的缓冲数组
 DatagramPacket dp = new DatagramPacket(bytes, bytes.length); // 用于接收数据的数据包对象
 // DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length);
 ds.receive(dp); // 接收数据,该方法返回值为void
 // 该方法是阻塞的,在执行到这里时会死等
 // 等待接收消息

 // 3.解析数据包
 byte[] data = dp.getData(); // 接收到的数据
 int len = dp.getLength(); // 接收数据的长度
 InetAddress address = dp.getAddress(); // 发送端的IP地址
 int port = dp.getPort();// 发送端的接口号

 System.out.println("接收到数据:" + new String(data, 0, len));
 System.out.println("该数据是从" + address + "的端口" + port + "上发出的。");
 }
}


UDP通信小练习

聊天室小程序,按照下面的要求实现程序

UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束

UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收

接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Receive {
 public static void main(String[] args) throws IOException {
 // 接收数据并回显

 // 创建连接,并监听10086端口
 DatagramSocket dSocket = new DatagramSocket(10086);
 System.out.println("聊天室已开启!");
 byte[] bytes = new byte[64 * 1024]; // 用于接收消息缓冲
 // 创建数据包对象,并指定bytes数组为缓冲数组
 DatagramPacket dPacket = new DatagramPacket(bytes, bytes.length);
 // 循环接收消息
 while (true){
 // 接收数据
 dSocket.receive(dPacket);

 // 回显消息
 // 源地址
 InetAddress srcAddr = dPacket.getAddress();
 // 源端口
 int srcPort = dPacket.getPort();
 // 获取接收到的数据
 byte[] data = dPacket.getData();
 // 获取接收到的数据长度
 int len = dPacket.getLength();
 // 显示数据
 System.out.println("来自" + srcAddr + ":" + srcPort + "的消息:");
 System.out.println(new String(data, 0, len));
 //System.out.println(new String(bytes, 0, len));
 }
 }
}

发送端:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class Send {
 public static void main(String[] args) throws IOException {
 // 目标地址和端口
 InetAddress address = InetAddress.getByName("localhost");
 int port = 10086;
 // 创建连接
 DatagramSocket dSocket = new DatagramSocket();

 // 发送提示消息
 /*
 StringBuffer hintStr = new StringBuffer();
 hintStr.append(new String(InetAddress.getLocalHost().getAddress()));
 hintStr.append("已上线!");
 DatagramPacket olHint = new DatagramPacket(hintStr.toString().getBytes(), hintStr.toString().getBytes().length, address, port);
 dSocket.send(olHint);
 */

 // 使用循环不断发送数据
 while (true) {
 // 读取键盘输入
 System.out.println("请输入聊天内容:");
 Scanner sc = new Scanner(System.in);
 String input = sc.nextLine();
 if ("886".equals(input)){
 // 结束程序
 System.out.println("退出聊天室。");
 dSocket.close(); // 关闭连接
 break;
 }else {
 // 创建数据包并发送
 // 创建数据包对象
 byte[] bytes = input.getBytes();
 // 创建数据包并指定地址和端口号
 DatagramPacket dPacket = new DatagramPacket(bytes, bytes.length, address, port);
 // 发送数据
 dSocket.send(dPacket);
 System.out.println("消息已发送");
 }
 }
 }
}


UDP的三种通信方式

单播

之前按照指定IP地址的方式即为单播。这里不再赘述。

组播

组播地址:224.0.0.0~239.255.255.255

其中224.0.0.0~224.0.0.255为预留的组播地址

在Java中如果使用多播,则需要使用MulticastSocket类的对象进行通信。在指定IP时需要使用多播(这里是组播)地址。

在接受和发送端都需要使用组播地址进行消息的接受和发送。

发送端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class MulticastSenderTest {
 public static void main(String[] args) throws IOException {
 /*
 组播发送端代码
 */

 // 创建MulticastSocket对象
 MulticastSocket mSocket = new MulticastSocket();

 // 创建DatagramPacket对象
 String msg = "你好,组播!";
 byte[] bytes = msg.getBytes(); // 获取消息的字节码数组
 InetAddress address = InetAddress.getByName("224.0.0.2"); //获取地址
 int port = 10000;
 // 创建数据包, 指定消息内容、消息长度、目标地址、目的端口
 DatagramPacket dPacket = new DatagramPacket(bytes, bytes.length, address, port);
 // 调用MulticastSocket发送数据
 mSocket.send(dPacket);
 // 关闭链接
 mSocket.close();
 }
}

接收端:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class MulticastReceiverTest {
 public static void main(String[] args) throws IOException {
 /*
 组播接收端代码
 */
 // 1. 创建MulticastSocket对象, 指定监听的端口
 MulticastSocket mSocket = new MulticastSocket(10000);

 // 2.将当前主机,添加到224.0.0.1这一组中
 InetAddress address = InetAddress.getByName("224.0.0.2");
 mSocket.joinGroup(address); // 此方法自JDK14启用

 // 3.创建DatagramPacket数据包对象
 byte[] bytes = new byte[1024];
 DatagramPacket dPacket = new DatagramPacket(bytes, 0, bytes.length);

 // 4.接受数据
 mSocket.receive(dPacket);

 // 5.解析数据
 int len = dPacket.getLength(); // 取得消息的长度
 String hostAddress = dPacket.getAddress().getHostAddress();
 String hostName = dPacket.getAddress().getHostName();

 System.out.println("IP为:" + hostAddress + ",主机名为:" + hostName + "的人,发送了数据:" + new String(bytes, 0, len));

 // 6.释放资源
 mSocket.close();
 }
}


广播

广播地址:255.255.255.255



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月29日 0

暂无评论

推荐阅读
  NPQODODLqddb   2024年05月17日   58   0   0 .NET
  mVIyUuLhKsxa   2024年05月17日   45   0   0 .NET
  XkHDHG7Y62UM   2024年05月17日   39   0   0 .NET
  f18CFixvrKz8   2024年05月18日   73   0   0 .NET
  Tnh5bgG19sRf   2024年05月20日   100   0   0 Java
  rBgzkhl6abbw   2024年05月18日   65   0   0 .NET
  MYrYhn3ObP4r   2024年05月17日   33   0   0 .NET
  S34pIcuyyIVd   2024年05月17日   50   0   0 .NET
  MYrYhn3ObP4r   2024年05月17日   28   0   0 .NET
93byl95AX42O