android UDP多点广播,并自动建立Socket连接
如题所示,本文要写的是两台或多台android设备,其中有一台作为服务端,则另外一台或几台作为客户端,然后通过UDP进行自动连接.其实现的原理很简单,服务端这一边通过MulticastSocket将自己的有关信息,如IP,端口等广播出去,同一个广播地址里面的客户端可以接收到该广播,并从中解析要相关的信息.
使用UDP进行多点广播,其基本的步骤如下:
一. 发送方发送广播步骤:
1. 创建一个MulticastSocket对象
MulticastSocket multicastSocket= new MulticastSocket(4444);
2. 创建一个 InetAddress .要使用多点广播,需要让一个数据报标有一组目标主机地址,其思想便是设置一组特殊网络地址作为多点广播地址,第一个多点广播地址都被看作是一个组,当客户端需要发送.接收广播信息时,加入该组就可以了.IP协议为多点广播提供这批特殊的IP地址,这些IP地址范围是224.0.0.0---239.255.255.255,其中224.0.0.0为系统自用.下面BROADCAST_IP是自己声明的一个String类型的变量,其范围但是前面所说的IP范围,比如BROADCAST_IP="224.224.224.224"
InetAddress serverAddress = InetAddress.getByName(BROADCAST_IP);
3. 需要广播出去的重要信息,比如服务端的局域网IP,或动态获得IP.下面介绍.
String ip= "192.168.137.60";
4. 将要广播出去的数据转为byte类型
byte data[] = ip.getBytes();
5. 创建一个DatagramPacket 对象,并指定要讲这个数据包发送到网络当中的哪个地址,以及端口号
DatagramPacket package = new DatagramPacket (data , data.length , serverAddress , 4444);
6. 将该MulticastSocket对象加入到指定的多点广播地址,MulticastSocket使用public void joinGroup(InetAddress mcastaddr) throws IOException方法加入指定组.
multicastSocket.joinGroup(serverAddress);
7. 调用MulticastSocket对象的send方法 发送数据
multicastSocket.send(package);
8. 如果不想再接收,广播数据,可以采用 public void leaveGroup(InetAddress mcastaddr) throws IOException multicastSocket.leaveGroup(serverAddress);二. 接收方接收广播步骤:
1. 创建一个MulticastSocket 对象,并指定监听的端口号
MulticastSocket multicastSocket= new MulticastSocket (4444);
2. 创建一个 InetAddress .
InetAddress serverAddress = InetAddress.getByName(BROADCAST_IP);
3. 将该MulticastSocket对象加入到指定的多点广播地址,MulticastSocket使用public void joinGroup(InetAddress mcastaddr) throws IOException方法加入指定组.
multicastSocket.joinGroup(serverAddress);
4. 创建一个byte数组用于接收
byte data[] = new byte[1024];
5. 创建一个空的DatagramPackage对象
DatagramPackage package = new DatagramPackage(data , data.length,serverAddress,BROADCAST_PORT);
6. 使用receive方法接收发送方所发送的数据,同时这也是一个阻塞的方法
socket.receive(package);
7. 得到发送过来的数据
String serverIP=new String(package.getData() , package.getOffset() , package.getLength());
8. 同样地,如果不想再接收,广播数据,可以采用 public void leaveGroup(InetAddress mcastaddr) throws IOException multicastSocket.leaveGroup(serverAddress); 下面,以一个实例来实现以上所说的局域网UDP广播socket自动连接的功能.首先,先看一下效果图. 首先是服务端广播IP信息 客户端接收服务端广播,得到服务端IP,并显示在界面上 服务端这一边启动的时候,如果检测到已经连接到局域网,那么,将自身IP显示出来,并新起一条线程,通过UDP将IP广播出去.界面上有一个按钮,可以切换广播状态,发送广播或者停止广播. 先声明一些变量:
private static String ip; //服务端ip private static int BROADCAST_PORT=9898;private static String BROADCAST_IP="224.0.0.1"; InetAddress inetAddress=null; Thread t=null; /*发送广播端的socket*/ MulticastSocket multicastSocket=null; /*发送广播的按钮*/ private Button sendUDPBrocast; private volatile boolean isRuning= true;TextView ipInfo;
按照上面发送广播步骤,在Activity的onCreate()方法里面执行下列语句,并另起一个线程广播IP数据.
try { inetAddress=InetAddress.getByName(BROADCAST_IP); multicastSocket=new MulticastSocket(BROADCAST_PORT); multicastSocket.setTimeToLive(1); multicastSocket.joinGroup(inetAddress); }catch(Exception e) { e.printStackTrace(); } t=new Thread(this); t.start();
在新起的线程run()方法里面,发送IP广播
//发送的数据包,局网内的所有地址都可以收到该数据包
public void run()
{ DatagramPacket dataPacket = null; //将本机的IP(这里可以写动态获取的IP)地址放到数据包里,其实server端接收到数据包后也能获取到发包方的IP的 byte[] data =ip.getBytes(); dataPacket = new DatagramPacket(data, data.length, inetAddress,BROADCAST_PORT); while(true) {if(isRuning) {try { multicastSocket.send(dataPacket); Thread.sleep(3000); System.out.println("再次发送ip地址广播:....."); } catch (Exception e) { e.printStackTrace(); } }}
}
运行上面服务端程序,在Logcat可见有下面的打印信息,说明服务端每隔几秒钟就向外广播自己的IP信息
(二)下面是客户端接收广播部分.客户端启动的时候,将自动接收服务端发出来的广播,并将IP信息解析出来,显示在界面上,如效果图所示: 同样的,声明一些必要变量:
private MulticastSocket multicastSocket=null; private static int BROADCAST_PORT=9898; private static String BROADCAST_IP="224.0.0.1"; InetAddress inetAddress=null; Thread thread=null; TextView ipInfo; private static String ip;
主方法里面,创造MulcastSocket,新起线程接收广播并解析服务端IP信息
thread=new Thread(this); try { multicastSocket = new MulticastSocket(BROADCAST_PORT); inetAddress=InetAddress.getByName(BROADCAST_IP); multicastSocket.joinGroup(inetAddress); thread.start(); } catch (Exception e1) { e1.printStackTrace(); }
在新起的线程里面,接收广播,得到服务端IP,但是,此时并不能直接将IP显示在TextView上面,因为,UI主线程之外的其他线程,无法更改主线程UI属性.所以,可以通过Hanler来传递信息,在主线程里面更改UI属性.
public void run( ) { // TODO Auto-generated method stubMessage msg=new Message();msg.what=1;byte buf[] = new byte[1024]; DatagramPacket dp =null; dp=new DatagramPacket(buf,buf.length,inetAddress,BROADCAST_PORT); while (true) { try { multicastSocket.receive(dp); Thread.sleep(3000); ip=new String(buf, 0, dp.getLength()); msg.obj=ip; myHandler.sendMessage(msg); System.out.println("检测到服务端IP : "+ip); } catch (Exception e) { e.printStackTrace(); } } }
以下是通过Handler更改主线程UI属性.
Handler myHandler=new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what==1) { ipInfo.append(msg.obj.toString()); } } };
执行完上面的客户端程序,后台打印信息便如下了.而效果图也准备显示了服务端的IP,既然已经能够获得服务端IP,那么,接下来,不管是基于TCP协议进行Socket通讯,还是继续用UDP协议进行socket通讯,都是轻而易举的事情了.
下面是客户端和服务端完整源代码的CSDN下载链接.
服务端完整代码 SocketAutoConnectServer.rar
客户端完整代码 SocketAutoConnectClient.rar
更多相关文章
- android 开发 socket发送会有部分乱码,串码,伴随着数据接收不完整
- Android(安卓)Broadcast receiver 编程
- Android使用高德地图地理围栏定位自动发送短信
- Android(安卓)网络管理
- Android(安卓)广播机制---BroadCast
- Android(安卓)2.2.1系统广播大全
- android应用程序监听SMS Intent广播
- TypeError:Cannot call method 'getItem' of null
- Android学习之Broadcast