组播
组播发送端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* @author yichuan@iscas.ac.cn
* @version 1.0
* @date 2021/10/20 14:44
*/
public class MulticastSender {
public static void main(String[] args) throws IOException
{
int port = 8888;
byte[] msg = "Connection successfully!!!".getBytes();
InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");
/*
* Java UDP组播应用程序主要通过MulticastSocket实例进行通信,它是DatagramSocket的是一个子类,
* 其中包含了一些额外的可以控制多播的属性.
*
* 注意:
*
* 多播数据报包实际上可以通过DatagramSocket发送,只需要简单地指定一个多播地址。
* 我们这里使用MulticastSocket,是因为它具有DatagramSocket没有的能力
*/
MulticastSocket client = new MulticastSocket();
DatagramPacket sendPack = new DatagramPacket(msg, msg.length,
inetRemoteAddr, port);
client.send(sendPack);
System.out.println("Client send msg complete");
client.close();
}
}
/**
* 组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。
* 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
* 224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
* 224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
* 239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
*
* 组播地址列表如下:
* 224.0.0.0 基准地址(保留)
* 224.0.0.1 所有主机的地址 (包括所有路由器地址)
* 224.0.0.2 所有组播路由器的地址
* 224.0.0.3 不分配
* 224.0.0.4 dvmrp路由器
* 224.0.0.5 所有ospf路由器
* 224.0.0.6 ospf DR/BDR
* 224.0.0.7 st路由器
* 224.0.0.8 st主机
* 224.0.0.9 rip-2路由器
* 224.0.0.10 Eigrp路由器
* 224.0.0.11 活动代理
* 224.0.0.12 dhcp 服务器/中继代理
* 224.0.0.13 所有pim路由器
* 224.0.0.14 rsvp封装
* 224.0.0.15 所有cbt路由器
* 224.0.0.16 指定sbm
* 224.0.0.17 所有sbms
* 224.0.0.18 vrrp
*/
组播接收端
import old.util.NetworkUtil;
import java.net.*;
import java.util.Arrays;
import java.util.List;
/**
* @author yichuan@iscas.ac.cn
* @version 1.0
* @date 2021/10/20 14:45
*/
public class MulticasReceiveNetworkCard {
public static void main(String[] args) throws Exception
{
//InetAddress inetRemoteAddr = InetAddress.getByName("224.0.0.5");
InetAddress group = InetAddress.getByName("224.0.0.5");
DatagramPacket recvPack = new DatagramPacket(new byte[1024], 1024);
//MulticastSocket server = new MulticastSocket(8888);
int port = 8888;
MulticastSocket socket = new MulticastSocket(port);
int randomPort = port + 30000;
List<NetworkInterface> addressList = NetworkUtil.getNetworkInterfaces();
for (NetworkInterface networkInterface : addressList) {
InetSocketAddress inetSocketAddress = new
InetSocketAddress(group, randomPort);
//将有效网卡加入组播
socket.joinGroup(inetSocketAddress, networkInterface);
randomPort++;
}
/*
* 如果是发送数据报包,可以不加入多播组; 如果是接收数据报包,必须加入多播组; 这里是接收数据报包,所以必须加入多播组;
*/
//server.joinGroup(inetRemoteAddr);
System.out.println("---------------------------------");
System.out.println("SocketServer current start......");
System.out.println("---------------------------------");
while (true)
{
socket.receive(recvPack);
//server.receive(recvPack);
byte[] recvByte = Arrays.copyOfRange(recvPack.getData(), 0,
recvPack.getLength());
System.out.println("SocketServer receive msg:" + new String(recvByte));
}
}
}
网卡工具类
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* @author yichuan@iscas.ac.cn
* @version 1.0
* @date 2021/10/25 10:48
*/
public class NetworkUtil {
private final static String LOCAL_IP = "127.0.0.1";
/**
* 获取本机有效所有网卡地址
*
* @return List<NetworkInterface> ip列表
* @throws
*/
public static List<NetworkInterface> getNetworkInterfaces() throws Exception {
List<NetworkInterface> localIPlist = new ArrayList<NetworkInterface>();
Enumeration<NetworkInterface> interfs =
NetworkInterface.getNetworkInterfaces();
if (interfs == null) {
return null;
}
while (interfs.hasMoreElements()) {
NetworkInterface interf = interfs.nextElement();
Enumeration<InetAddress> addres = interf.getInetAddresses();
while (addres.hasMoreElements()) {
InetAddress in = addres.nextElement();
if (in instanceof Inet4Address) {
if (!LOCAL_IP.equals(in.getHostAddress())){
localIPlist.add(interf);
}
}
}
}
return localIPlist;
}
}
单播
单播发送端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author yichuan@iscas.ac.cn
* @version 1.0
* @date 2021/10/20 9:12
*/
/*
* 实现UDP协议的发送端:
* 实现封装数据的类 java.net.DatagramPacket 将你的数据包装
* 实现数据传输类 java.net.DatagramSocket 将数据包发出去
*
* 实现步骤:
* 1.创建DatagramPacket对象,封装数据,接收的地址和端口
* 2.创建DatagramSocket对象,
* 3.调用DatagramSocket类的方法send,发送数据包
* 4.关闭资源
*
* DatagramPacket构造方法:
* DatagramPacket(byte[] buf,int length,InetAddress address,int port)
*
* DatagramSocket构造方法:
* DatagramSocket()空参数
* 方法:send(DatagramPacket d)
*
*
*/
public class UDPSend {
public static void main(String[] args) throws IOException {
//创建数据包对象,封装要发送的数据,接受端IP,端口
byte[] data="你好UDP".getBytes();
//创建InetAddress对象,封装自己的IP地址
InetAddress inet=InetAddress.getByName("127.0.0.1");
DatagramPacket dp=new DatagramPacket(data,data.length,inet,6000);
//创建DatagramSocket对象,数据包的发送和接受对象
DatagramSocket ds=new DatagramSocket();
//调用ds对象的方法send,发送数据包
ds.send(dp);
ds.close();
}
}
单播接收端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author yichuan@iscas.ac.cn
* @version 1.0
* @date 2021/10/20 9:17
*/
/*
* 实现UDP接收端
* 实现封装数据包java.net.DatagramPacket 将数据接收
* 实现输出传输 java.net.DatagramSocket 接受数据包
*
* 实现步骤:
* 1.创建DatagramSocket对象,绑定端口号
* 要和发送数据端口号一致
* 2.创建字节数组,接受发来的数组
* 3.创建数据包对象DatagramPacket
* 4.调用DatagramSocket对象方法 receive(DatagramPacket dp)
* 接受数据,数据放在数据包中
* 5.拆包
* 发送的IP地址
* 数据包对象DatagramPacket()方法getAddress()获取的是发送端的IP地址对象
* 接受到的字节个数
* 数据包对象DatagramPacket()方法getLength()
* 发送方的端口号
* 数据包对象DatagramPacket()方法getPort()
* 6.关闭资源
*/
public class UDPReceive {
public static void main(String[] args) throws IOException {
//创建数据包传输对象DatagramSocket 绑定端口号
DatagramSocket ds=new DatagramSocket(6000);
//创建字节数组
byte[] data=new byte[1024];
//创建数据包对象,传递字节数组
DatagramPacket dp=new DatagramPacket(data, data.length);
//调用ds对象的方法receive传递数据包
ds.receive(dp);
//获取发送端的IP地址对象
String ip=dp.getAddress().getHostAddress();
//获取发送的端口号
int port=dp.getPort();
//获取接收到的字节数
int length=dp.getLength();
System.out.println(new String(data,0,length)+"...."+ip+":"+port);
ds.close();
}
}