因项目中需要添加Android移动设备中同一局域网下的所有设备,故做一下记录,以供以后使用
package com.tvt.network;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class ServerLocal
{
public static final int FLAG_MULTIHEAD = mmioFOURCC1('M', 'H', 'E', 'D');
public static final int MULTICAST_VER = 0x10001;
public static final int MULTICAST_CMD_SEARCH = 1; // 由搜索器发出的搜索指令
public static String TAG = "ServerLocal";
private InetAddress m_BroadcastAddr = null;
private Thread thread;
private boolean m_bBroadcastStarted = false;
private byte[] m_BroadcastBuffer = new byte[1024];
private static String LocalAddress = "234.55.55.55";
private static int LocalPort = 23456;
private MulticastSocket m_MulticastSocket;
private Timer m_PlayTimer;
private TimerTask m_PlayTimerTask;
static int mmioFOURCC1(char ch0, char ch1, char ch2, char ch3)
{
return ((int) (byte) ch0 | (int) (((byte) ch1) << 8)) | (int) (((byte) ch2) << 16) | ((int) (((byte) ch3) << 24));
}
public ServerLocal()
{
}
/* 开启连接,加入局域网 */
public void ConnectDevice()
{
try
{
m_BroadcastAddr = InetAddress.getByName(LocalAddress);
m_MulticastSocket = new MulticastSocket(LocalPort);
m_MulticastSocket.joinGroup(m_BroadcastAddr);
m_MulticastSocket.setTimeToLive(255);
m_MulticastSocket.setBroadcast(true);
startReceiveThread();
}
catch (IOException e)
{
e.printStackTrace();
}
}
/* 打开接收和搜索线程 */
public void startReceiveThread()
{
m_PlayTimer = new Timer();
m_PlayTimerTask = new TimerTask()
{
public void run()
{
SerachDevice();
}
};
m_PlayTimer.schedule(m_PlayTimerTask, 0, 10000);// 十秒搜索一次
if (thread == null)
{
thread = new Thread(null, doBackgroundThreadProcessing, "SocketThread");
thread.start();
}
}
public Runnable doBackgroundThreadProcessing = new Runnable()
{
public void run()
{
backgroundThreadProcessing();
}
};
public void backgroundThreadProcessing()
{
m_bBroadcastStarted = true;
while (m_bBroadcastStarted)
{
DatagramPacket packet = new DatagramPacket(m_BroadcastBuffer, m_BroadcastBuffer.length);
try
{
if (m_MulticastSocket == null)
{
continue;
}
m_MulticastSocket.receive(packet);
byte[] data = packet.getData();
MultiCastInfo multicastInfo = MultiCastInfo.deserialize(data, 0);
if (multicastInfo.ipaddr == 0)
{
continue;
}
//处理接收的数据
}
catch (IOException e)
{
// e.printStackTrace();
}
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
public void stopSearchDevice()
{
m_bBroadcastStarted = false;
if (m_PlayTimer != null)
{
m_PlayTimer.cancel();
}
if (m_PlayTimerTask != null)
{
m_PlayTimerTask.cancel();
}
if (m_MulticastSocket != null)
{
m_MulticastSocket.close();
m_MulticastSocket = null;
}
if (m_DeviceInfo != null)
{
m_DeviceInfo.clear();
m_DeviceInfo = null;
}
}
public void SerachDevice()
{
MultiCastInfo info = new MultiCastInfo();
info.head = FLAG_MULTIHEAD;
info.cmd = MULTICAST_CMD_SEARCH;
info.ver = MULTICAST_VER;
byte[] cmdBuff = new byte[MultiCastInfo.GetStructSize()];
try
{
DatagramPacket dataPacket = new DatagramPacket(cmdBuff, cmdBuff.length, m_BroadcastAddr, 23456);
dataPacket.setData(info.serialize());
m_MulticastSocket.send(dataPacket);
}
catch (Exception e)
{
}
}
public String IntToBinaryString(int iValue)// 将int类型转换为二进制字符串
{
StringBuffer sb = new StringBuffer("");
sb.append(String.valueOf(iValue & 0x000000FF));
sb.append(".");
sb.append(String.valueOf((iValue & 0x0000FFFF) >>> 8));
sb.append(".");
sb.append(String.valueOf((iValue & 0x00FFFFFF) >>> 16)); // 将高8位置0,然后右移16位
sb.append(".");
sb.append(String.valueOf(iValue >>> 24));// 直接右移24位
return sb.toString();
}
}
class MultiCastInfo
{
public int head; // 是FLAG_MULTIHEAD
public int ver; // 结构信息版本
public int cmd;
public byte[] DevName = new byte[20]; // 如果此编码格式为UTF8请将版本号设置为0x10001
public byte[] MacAddr = new byte[6];
public short netport;
public int ipaddr;
public int netmask;
public int route;
public int softver;
public int softbuilddate; // 没有用了
public short nHttpPort;
public byte[] NoUsed = new byte[2];
public int deviceType;
public int productType;
public int kernelVersion;
public int inputform;
public int devVer; // 设备硬件版本号
public byte[] szPasswd = new byte[28]; // 设置IP必须输入正确的admin密码,采用base64编码
public byte[] Resved = new byte[28]; // 以后增加功能就利用这些字节
public static int GetStructSize()
{
return 140;
}
public byte[] serialize() throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
MyUtil m_util = new MyUtil();
head = m_util.ntohl(head);
dos.writeInt(head);
ver = m_util.ntohl(ver);
dos.writeInt(ver);
cmd = m_util.ntohl(cmd);
dos.writeInt(cmd);
dos.write(DevName, 0, DevName.length);
dos.write(MacAddr, 0, MacAddr.length);
dos.writeShort(netport);
ipaddr = m_util.ntohl(ipaddr);
dos.writeInt(ipaddr);
netmask = m_util.ntohl(netmask);
dos.writeInt(netmask);
route = m_util.ntohl(route);
dos.writeInt(route);
softver = m_util.ntohl(softver);
dos.writeInt(softver);
softbuilddate = m_util.ntohl(softbuilddate);
dos.writeInt(softbuilddate);
dos.writeShort(nHttpPort);
dos.write(NoUsed, 0, NoUsed.length);
deviceType = m_util.ntohl(deviceType);
dos.writeInt(deviceType);
productType = m_util.ntohl(productType);
dos.writeInt(productType);
kernelVersion = m_util.ntohl(kernelVersion);
dos.writeInt(kernelVersion);
inputform = m_util.ntohl(inputform);
dos.writeInt(inputform);
devVer = m_util.ntohl(devVer);
dos.writeInt(devVer);
dos.write(szPasswd, 0, szPasswd.length);
dos.write(Resved, 0, Resved.length);
baos.close();
dos.close();
return baos.toByteArray();
}
public static MultiCastInfo deserialize(byte[] data, int offset) throws IOException
{
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bais);
MyUtil m_util = new MyUtil();
MultiCastInfo info = new MultiCastInfo();
dis.read(data, 0, offset);
byte[] testbyte = new byte[28];
dis.read(testbyte, 0, 4);
info.head = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.ver = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.cmd = m_util.bytes2int(testbyte);
dis.read(info.DevName, 0, 20);
dis.read(info.MacAddr, 0, 6);
dis.read(testbyte, 0, 2);
info.netport = m_util.bytes2short(testbyte);
dis.read(testbyte, 0, 4);
info.ipaddr = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.netmask = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.route = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.softver = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.softbuilddate = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 2);
info.nHttpPort = m_util.bytes2short(testbyte);
dis.read(info.NoUsed, 0, info.NoUsed.length);
dis.read(testbyte, 0, 4);
info.deviceType = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.productType = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.kernelVersion = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.inputform = m_util.bytes2int(testbyte);
dis.read(testbyte, 0, 4);
info.devVer = m_util.bytes2int(testbyte);
dis.read(info.szPasswd, 0, info.szPasswd.length);
dis.read(info.Resved, 0, info.Resved.length);
bais.close();
dis.close();
return info;
}
}