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