android UDP多点广播,并自动建立Socket连接

来源:互联网 发布:催情药在淘宝叫什么 编辑:程序博客网 时间:2024/06/06 05:28


2013-11-20 10:03:58|  分类: Android |  标签:广播  |举报|字号 订阅

  下载LOFTER我的照片书  |

如题所示,本文要写的是两台或多台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广播出去.界面上有一个按钮,可以切换广播状态,发送广播或者停止广播.
先声明一些变量:
[java] view plaincopy
  1.        private static String ip; //服务端ip     
  2. private static int BROADCAST_PORT=9898;  
  3. private static String BROADCAST_IP="224.0.0.1";     
  4. InetAddress inetAddress=null;   
  5. Thread t=null;     
  6. /*发送广播端的socket*/    
  7.    MulticastSocket multicastSocket=null;     
  8.    /*发送广播的按钮*/     
  9.    private Button sendUDPBrocast;   
  10. private volatile boolean isRuning= true;  
  11. TextView ipInfo;  

按照上面发送广播步骤,在Activity的onCreate()方法里面执行下列语句,并另起一个线程广播IP数据.

[java] view plaincopy
  1. try   
  2.         {  
  3.             inetAddress=InetAddress.getByName(BROADCAST_IP);  
  4.             multicastSocket=new MulticastSocket(BROADCAST_PORT);  
  5.             multicastSocket.setTimeToLive(1);  
  6.             multicastSocket.joinGroup(inetAddress);  
  7.               
  8.         }catch(Exception e)  
  9.         {  
  10.             e.printStackTrace();  
  11.               
  12.         }  
  13.          t=new Thread(this);   
  14.          t.start();   

在新起的线程run()方法里面,发送IP广播
[java] view plaincopy
  1. //发送的数据包,局网内的所有地址都可以收到该数据包    
[java] view plaincopy
  1. public void run()  
[java] view plaincopy
  1. {  
  2.         DatagramPacket dataPacket = null;            
  3.         //将本机的IP(这里可以写动态获取的IP)地址放到数据包里,其实server端接收到数据包后也能获取到发包方的IP的    
  4.         byte[] data =ip.getBytes();     
  5.         dataPacket = new DatagramPacket(data, data.length, inetAddress,BROADCAST_PORT);    
  6.         while(true)    
  7.         {  
  8.             if(isRuning)   
  9.             {  
  10.                 try    
  11.                 {    
  12.                    multicastSocket.send(dataPacket);   
  13.                    Thread.sleep(3000);    
  14.                    System.out.println("再次发送ip地址广播:.....");    
  15.                 } catch (Exception e)                
  16.                 {      
  17.                     e.printStackTrace();       
  18.                 }   
  19.             }  
  20.         }   
[java] view plaincopy
  1. }  


运行上面服务端程序,在Logcat可见有下面的打印信息,说明服务端每隔几秒钟就向外广播自己的IP信息



(二)下面是客户端接收广播部分.客户端启动的时候,将自动接收服务端发出来的广播,并将IP信息解析出来,显示在界面上,如效果图所示:
同样的,声明一些必要变量:
[java] view plaincopy
  1. private MulticastSocket multicastSocket=null;    
  2.     private static int BROADCAST_PORT=9898;    
  3.     private static String BROADCAST_IP="224.0.0.1";      
  4.     InetAddress inetAddress=null;     
  5.     Thread thread=null;  
  6.     TextView ipInfo;  
  7.     private static String ip;  

主方法里面,创造MulcastSocket,新起线程接收广播并解析服务端IP信息
[java] view plaincopy
  1. thread=new Thread(this);   
  2.         try      
  3.         {       
  4.              multicastSocket = new MulticastSocket(BROADCAST_PORT);    
  5.              inetAddress=InetAddress.getByName(BROADCAST_IP);   
  6.              multicastSocket.joinGroup(inetAddress);    
  7.              thread.start();  
  8.   
  9.         } catch (Exception e1)     
  10.         {       
  11.             e1.printStackTrace();    
  12.         }   
  13.           


在新起的线程里面,接收广播,得到服务端IP,但是,此时并不能直接将IP显示在TextView上面,因为,UI主线程之外的其他线程,无法更改主线程UI属性.所以,可以通过Hanler来传递信息,在主线程里面更改UI属性.
[java] view plaincopy
  1. public void run( )      
  2.     {     
  3.         // TODO Auto-generated method stub  
  4.         Message msg=new Message();  
  5.         msg.what=1;  
  6.         byte buf[] = new byte[1024];    
  7.         DatagramPacket dp =null;      
  8.         dp=new DatagramPacket(buf,buf.length,inetAddress,BROADCAST_PORT);   
  9.            
  10.             while (true)       
  11.             {        
  12.                 try                   
  13.                 {               
  14.                     multicastSocket.receive(dp);  
  15.                     Thread.sleep(3000);  
  16.                     ip=new String(buf, 0, dp.getLength());  
  17.                     msg.obj=ip;       
  18.                     myHandler.sendMessage(msg);  
  19.                     System.out.println("检测到服务端IP : "+ip);     
  20.                 } catch (Exception e)      
  21.                 {        
  22.                     e.printStackTrace();            
  23.                 }      
  24.             }      
  25.     }   


以下是通过Handler更改主线程UI属性.
[java] view plaincopy
  1. Handler  myHandler=new Handler()   
  2.      {  
  3.         @Override   
  4.         public void handleMessage(Message msg)  
  5.         {  
  6.             super.handleMessage(msg);  
  7.             if(msg.what==1)  
  8.             {   
  9.                  ipInfo.append(msg.obj.toString());  
  10.             }  
  11.         }  
  12.      };  

执行完上面的客户端程序,后台打印信息便如下了.而效果图也准备显示了服务端的IP,既然已经能够获得服务端IP,那么,接下来,不管是基于TCP协议进行Socket通讯,还是继续用UDP协议进行socket通讯,都是轻而易举的事情了.

0 0
原创粉丝点击