Java 组播收发程序实例
package def;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class Multicast {
public static final int LOCAL_HOST_PORT = 1900;
public static final int DESTINATION_PORT = 1900;
public static final int DATA_LEN = 64 * 1024;
public static final String GROUP_ADDRESS = "239.255.255.250";
public static void main(String[] args) {
// 组播接收
new Thread(new Runnable() {
public void run() {
try {
receive();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
// 组播发送
new Thread(new Runnable() {
@Override
public void run() {
try {
send();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private static void receive() throws Exception {
InetAddress inetAddress = InetAddress.getByName(GROUP_ADDRESS);// 多播组
MulticastSocket multicastSocket = new MulticastSocket(LOCAL_HOST_PORT);// 新建一个socket,绑定接收端口1900
multicastSocket.joinGroup(inetAddress);// 加入多播组
while (true) {
byte[] inBuff = new byte[DATA_LEN];
DatagramPacket inPacket = new DatagramPacket(inBuff, inBuff.length);// 构造接收数据报,包含要接收的数据、长度
inPacket.setData(inBuff);
multicastSocket.receive(inPacket);// 接收数据报
System.out.println("onReceive: address = [" + inPacket.getAddress().toString() + "], port = ["
+ inPacket.getPort() + "], data = ["
+ new String(inPacket.getData(), inPacket.getOffset(), inPacket.getLength()) + "]");
}
}
private static void send() throws Exception {
int i = 0;
InetAddress group = InetAddress.getByName(GROUP_ADDRESS);
MulticastSocket multicastSocket = new MulticastSocket();
while (true) {
byte[] bytes = String.valueOf(++i).getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, group, DESTINATION_PORT);// 发送数据报,指定目标端口和目标地址
multicastSocket.send(datagramPacket);
Thread.sleep(300);
}
}
}
如果是android程序,那么还需要加上以下部分:
(1)权限
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
(2)申请权限
protected void setWiFiMulticastLock(boolean enable) {
if (multicastLock == null) {
multicastLock = wifiManager.createMulticastLock(getClass().getSimpleName());
}
if (enable) {
if (multicastLock.isHeld()) {
logger.w("WiFi multicast lock already acquired");
} else {
logger.i("WiFi multicast lock acquired");
multicastLock.acquire();
}
} else {
if (multicastLock.isHeld()) {
logger.i("WiFi multicast lock released");
multicastLock.release();
} else {
logger.w("WiFi multicast lock already released");
}
}
}
protected void setWifiLock(boolean enable) {
if (wifiLock == null) {
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, getClass().getSimpleName());
}
if (enable) {
if (wifiLock.isHeld()) {
logger.w("WiFi lock already acquired");
} else {
logger.i("WiFi lock acquired");
wifiLock.acquire();
}
} else {
if (wifiLock.isHeld()) {
logger.i("WiFi lock released");
wifiLock.release();
} else {
logger.w("WiFi lock already released");
}
}
}
android手机上对组播的功能支持并不完美,很多手机在某些路由器下,无法接收到组播。
如上同样的程序,相同的手机,在网络切换后收不到组播。经tcpdump抓包数据查看,也没有ip.dst==239.255.255.250 upd数据包。