DatagramSocket socket = new DatagramSocket();
//设置接收等待时长
socket.setSoTimeout(LanCommConfig.RECEIVE_TIME_OUT);
byte[] sendData = new byte[1024];
//使用广播形式(目标地址设为255.255.255.255)的udp数据包
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), Const.DEVICE_BROADCAST_PORT);
byte[] hostAddress = Utils.getLocalIPAddress();
byte[] b="啦啦啦啦啦啦啦啦啦噢噢噢噢噢噢噢噢".getBytes();
byte[] broadcastData = packBroadcastData(hostAddress, b);
sendPacket.setData(broadcastData);
//发送udp数据包
socket.send(sendPacket);
Log.v(TAG, Utils.getDeviceIp() + Const.SEND_SYMBOL + "局域网广播 成功");
/**
* 协议规范
* #(1) + packageType(1) + ip(4) + dataLength(4) + [data]
*
* @param bytes
* @param hostAddress
* @return
*/
private int type = Const.PACKET_TYPE_BROADCAST;
private byte[] packBroadcastData(byte[] hostAddress, byte[] bytes) {
// Trace.d(TAG, "packBroadcastData() :" + Arrays.toString(hostAddress));
// Trace.d(TAG, "packBroadcastData() : " + Arrays.toString(bytes));
byte[] lengthBytes = ConvertUtils.intToByteArray(bytes.length);
byte[] data = new byte[2 + hostAddress.length + bytes.length + lengthBytes.length];
data[0] = Const.PACKET_PREFIX;
data[1] = (byte) type;
// Trace.d(TAG, "packBroadcastData() : " + Arrays.toString(lengthBytes));
System.arraycopy(hostAddress, 0, data, 2, hostAddress.length);
System.arraycopy(lengthBytes, 0, data, 2 + hostAddress.length, lengthBytes.length);
if (bytes != null && bytes.length != 0) {
System.arraycopy(bytes, 0, data, 2 + hostAddress.length + lengthBytes.length, bytes.length);
}
Log.v(TAG, Utils.getDeviceIp() + Const.SEND_SYMBOL + "局域网广播 package data:\r\n" + Arrays.toString(data));
return data;
}
把自身的ip地址发送过去。
package com.fighter.lancomm.utils;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
/**
* @author sts
* @date 2020/1/15
*/
public class Utils {
/**
* 获取内网IP地址
*
* @return
* @throws SocketException
*/
public static byte[] getLocalIPAddress() throws SocketException {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && (inetAddress instanceof Inet4Address)) {
return inetAddress.getAddress();
}
}
}
return new byte[4];
}
public static String ipbyteToString(byte[] ip) throws UnknownHostException {
return InetAddress.getByAddress(ip).getHostAddress();
}
public static String getDeviceIp() {
try {
byte[] localIPAddress = getLocalIPAddress();
return Utils.ipbyteToString(localIPAddress);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "";
}
}
UDP编程常常使用,但是广播和多播倒很少用到,依据协议的样子,在局域网内该有很大的作为。特意写了两个例子测试一下了广播 。测试连接放在最前面。
组播是一种数据包传输方式,当有多台主机同时成为一个数据包的接受者时,出于对带宽和CPU负担的考虑,组播成为了一种最佳选择。
组播通过把224.0.0.0-239.255.255.255的D类地址作为目的地址,有一台源主机发出目的地址是以上范围组播地址的报文,在网络中,如果有其他主机对于这个组的报文有兴趣的,可以申请加入这个组,并可以接受这个组,而其他不是这个组的成员是无法接受到这个组的报文的。
众所周知的D类IP地址:
D类地址用途
224.0.0.1在一个子网上的所有主机
224.0.0.2在一个子网上的所有路由器
224.0.0.4所有DVMRP协议的路由器
224.0.0.5所有开放最短路径优先(OSPF)路由器
224.0.0.6所有OSPF指定路由器
224.0.0.9所有RIPv2路由器
224.0.0.13所有PIM协议路由器
224.0.0.0-224.0.0.255保留作本地使用,做管理和维护任务
239.0.0.0-239.255.255.255留用做管理使用
255.255.255.255 广播,貌似路由器会丢掉这些数据包的,具体查查资料吧UD