用java做了个UDP多播压力测试
发现即使其他主机没有加入多播IP组也会受到阻塞网络,无法与其他主机网络通讯。
另外一个测试,用UDP点对点(单播)压力测试,其他主机是不受影响的
从这测试结果来看,UDP多播可能IP底层多播与广播没有区别同样会占用局域网内的所有主机的带宽。
希望大神能给个解释,是测试有问题还是多播IP底层确实与广播一样?
代码:
Main.java
package com.main;
import com.network.udp.MulticastServer;
import com.network.udp.UdpCallback;
import com.network.udp.UdpServer;
public class Main {
static UdpServer udp;
static MulticastServer multi1;
public static void main(String[] args) {
udp = new UdpServer(udpcall);
udp.start(8000);
multi1 = new MulticastServer(multicall1);
multi1.start("224.100.100.1", 9000); //UDP多播地址与端口
byte[] data = new byte[(20 * 1024)];
while(true){
//udp.send("192.168.88.227", 1001, data, data.length); //UDP点对点压力测试
multi1.send(9001, data, data.length); //UDP多播压力测试,发送数据
}
}
public static UdpCallback udpcall = new UdpCallback() {
public void onReceive(int port, byte[] data, int length) {
System.out.print("1onReceive port : " + port + ", length : " + length );
System.out.print("\r");
}
};
public static UdpCallback multicall1 = new UdpCallback() {
public void onReceive(int port, byte[] data, int length) {
System.out.print("2onReceive port : " + port + ", length : " + length );
System.out.print("\r");
}
};
public static UdpCallback multicall2 = new UdpCallback() {
public void onReceive(int port, byte[] data, int length) {
System.out.print("3onReceive port : " + port + ", length : " + length );
System.out.print("\r");
}
};
}
UdpCallback.java
package com.network.udp;
public interface UdpCallback {
public void onReceive(int port, byte[] data, int length);
}
MulticastServer.java
package com.network.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
public class MulticastServer {
private final int MAX_SIZE = (1000 * 1024);// 1000Kb限制
private int port = 8888;
private String address = "224.0.0.1";
private MulticastSocket multicastSocket = null;
private UdpCallback call;
public MulticastServer(UdpCallback call) {
// TODO 自动生成的构造函数存根
this.call = call;
}
public void start(String address, int port) {
this.address = address;
this.port = port;
receiveMessage();
}
public void stop() {
if (multicastSocket != null) {
multicastSocket.close();
}
}
public void send(int port, byte[] data, int length) {
if (multicastSocket != null) {
try {
InetAddress group = InetAddress.getByName(address);
DatagramPacket datagramPacket = new DatagramPacket(data, length, group, port);
multicastSocket.send(datagramPacket);
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
private void receiveMessage() {
if (multicastSocket != null) {
stop();
}
new Thread() {
public void run() {
byte[] buffer;
DatagramPacket datagramPacket = null;
try {
InetAddress group = InetAddress.getByName(address);
multicastSocket = new MulticastSocket(port);
multicastSocket.joinGroup(group);
buffer = new byte[MAX_SIZE];
datagramPacket = new DatagramPacket(buffer, buffer.length);
} catch (UnknownHostException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return;
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return;
}
while (true) {
try {
multicastSocket.receive(datagramPacket);
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
break;
}
if (datagramPacket.getLength() != 0) {
call.onReceive(datagramPacket.getPort(), datagramPacket.getData(), datagramPacket.getLength());
}
}
multicastSocket.close();
multicastSocket = null;
}
}.start();
}
}
UdpServer.java
package com.network.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class UdpServer {
private final int MAX_SIZE = (1000 * 1024);// 1000Kb限制
private UdpCallback call = null;
private boolean rxThread = false;
private DatagramSocket socket = null;
public int port = 8080;
public String group = null;
public UdpServer(UdpCallback call) {
// TODO 自动生成的构造函数存根
this.call = call;
}
public void start(int port) {
this.port = port;
receiveMessage();
}
public void start(String group, int port) {
this.group = group;
this.port = port;
receiveMessage();
}
public void stop() {
if (socket != null) {
rxThread = false;
socket.close();
socket = null;
}
}
private void receiveMessage() {
if (socket != null) {
stop();
}
new Thread() {
public void run() {
byte[] receBuf;
DatagramPacket packet;
try {
socket = new DatagramSocket(port);
socket.setSendBufferSize(MAX_SIZE);
socket.setReceiveBufferSize(MAX_SIZE);
receBuf = new byte[MAX_SIZE];
packet = new DatagramPacket(receBuf, receBuf.length);
rxThread = true;
} catch (SocketException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
return;
}
while (rxThread) {
try {
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
break;
}
if (packet.getLength() != 0) {
call.onReceive(packet.getPort(), packet.getData(), packet.getLength());
}
}
socket.close();
socket = null;
}
}.start();
}
public void send(String ip, int port, byte[] data, int length) {
if (socket != null) {
try {
InetAddress serverAddress = InetAddress.getByName(ip);
DatagramPacket pack = new DatagramPacket(data, length, serverAddress, port);
socket.send(pack);
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}