image.png
    image.png
    在配置这里选中,允许并发实例, 这样就是开多个客户端(并发)
    image.png

    1. package com.itheima.d3_udp2;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. import java.net.InetAddress;
    5. import java.util.Scanner;
    6. /**
    7. * 发送端 多发多收
    8. */
    9. public class ClientDemo1 {
    10. public static void main(String[] args) throws Exception {
    11. // 测试发送数据的时候,先启动服务端
    12. System.out.println("==================客户端启动=================");
    13. // 1. 创建发送端对象: 发送端自带默认的端口号
    14. DatagramSocket socket = new DatagramSocket(); // 发送端不用定义端口,有默认的端口
    15. // DatagramSocket socket = new DatagramSocket(6666); 这个里面的参数可以自定义参数
    16. // 定义一个扫描器,扫描输入的数据,以后都使用sc.nextLine方法,每次扫描一行的数据
    17. Scanner sc = new Scanner(System.in);
    18. while (true) { // 定义一个死循环,一直发送给服务端
    19. // 不要用next()方法,因为该方法扫描到一个空格,就会停止扫描
    20. System.out.println("请说:");
    21. String msg = sc.nextLine();
    22. if ("exit".equals(msg)){ // 阿里巴巴的条约,如果输入exit就退出
    23. System.out.println("离线成功");
    24. socket.close(); // 退出就释放资源退出管道
    25. break; // 跳出死循环
    26. }
    27. // 2. 创建应该数据包对象封装数据(韭菜盒子)
    28. byte[] buffer = msg.getBytes(); // getBytes方法是将字符串转换为数组(返回值是字节数组)
    29. // 这里定义的DatagramPacket相当于是一个韭菜盘子的对象(数据包对象),将字节数组装进去
    30. // 双方都是由数据包对象传递
    31. DatagramPacket packet = new DatagramPacket(buffer,buffer.length, InetAddress.getLocalHost(),8888);
    32. // 3. 发送数据出去
    33. socket.send(packet); // 使用发送端对象的send方法,将数据包发出去
    34. }
    35. }
    36. }
    1. package com.itheima.d3_udp2;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. /**
    5. * 服务端
    6. */
    7. public class ServiceDemo02 {
    8. public static void main(String[] args) throws Exception {
    9. // 测试发送数据的时候,先启动服务端
    10. System.out.println("==================服务端启动=================");
    11. // 创建接收端对象:注册端口(人)
    12. DatagramSocket socket = new DatagramSocket(8888); // 这个时候服务端要指定端口方便接收数据
    13. // 创建一个数据包对象接收数据(韭菜盒子) 每次发送的---最大是64kb(自己定义的)
    14. byte[] buffer = new byte[1024 * 64]; // 相当于里面是64kb 的数据
    15. DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    16. while (true) { // 定义一个死循环不断接收数据
    17. // 3. 等待接收数据
    18. socket.receive(packet); // receive 接收的意思
    19. // 4. 取出数据即可(数据在packet里面数据包里面)
    20. // 读取多少倒出多少
    21. int len = packet.getLength();// 将数据包的长度取出来,这样可以,从索引0开始,到该长度结束,(实现,有多少数据,倒多少数据)
    22. String rs = new String(buffer,0,len); // 将buffer字节数组转换成字符串(根据字节数组内容来创建字符串)
    23. System.out.println("收到了来自:" + packet.getAddress() + "对方端口是: " + packet.getPort() + "的消息:" + rs); // 将读取的数据打印出来
    24. // 获取发送端(客户端的ip和端口)
    25. // 先获取客户端的ip 使用getSocketAddress方法,可以理解为获取管道的地址(ip地址),因为他们数据包发送是中间有管道的,
    26. // 每个类都具有toString方法(int是基础数据类型,没有toSting方法),作用是返回对象的字符串表示(类名+符号@+对象的哈希码)。
    27. String ip = packet.getSocketAddress().toString(); // 用toString方法,将其转换成字符串形式
    28. System.out.println("对方地址:" + ip);
    29. int port = packet.getPort(); // 用toString方法,将其转换成字符串形式
    30. System.out.println("对方端口:" + port);
    31. // 数据包发完之后把管道关掉
    32. // socket.close(); // 服务端不要关管道,要不然,接受一次数据后,就不会继续接收了
    33. }
    34. }
    35. }