Android 通过UDP广播建立Socket

前言:项目中遇到的实际问题,Android手机想要和局域网中的某个主机进行Socket通信,但是Socket连接前却无法获知该主机的IP, 为了建立Socket,就需要Android手机在局域网内发送UDP广播,从而获得目的主机的IP。


一、 关于 TCP/UDP

项目中主机内置的Wifi模块自带被搜索功能:手机(Client)通过UDP广播发送一个口令,默认口令为:”HF-A11ASSISTHREAD”;Server收到正确的口令,就会向Client回复自己的IP、MAC、模块名称

  • 百度百科有介绍TCP/UDP协议

    Android 通过UDP广播建立Socket_第1张图片

    1. TCP是面向连接的协议,正式通信前需要建立连接,但是如果连对方的ip、port都不知道,是无法建立连接的

    2. UDP是面向非连接的协议,不管对方状态,直接把包发过去

    3. 两种协议适用不同的场合


二、Android UDP 编程

1. Android UDP 编程的 API 的介绍有很多

这个翻译的挺好:java DatagramPacket API

2. 代码

  • 开线程,将UDP的收发写到新的线程里
UDPThread thread = new UDPThread();
Thread udpThread = new Thread(thread);
udpThread.start();  
  • 实现代码
// Wifi模块指定的广播口令,需要转换成UDP要求的byte格式
byte[] sendBuf="HF-A11ASSISTHREAD".getBytes();  

 try {          
    // 发送
    DatagramSocket sendSocket = new DatagramSocket();                   
    InetAddress broadcastAddress=InetAddress.getByName("192.168.1.255");                    
    DatagramPacket sendPacket=new DatagramPacket(sendBuf,sendBuf.length,broadcastAddress,48899);    
    sendSocket.send(sendPacket);

    // 接收
    byte[] receiveBuf = new byte[64];
    DatagramPacket receivePacket = new DatagramPacket(receiveBuf, receiveBuf.length);                   
    sendSocket.receive(receivePacket);                                          

    // 获得Wifi模块回复的自身IP
    InetAddress address = receivePacket.getAddress();
    String data = receivePacket.getData().toString();
    System.out.println(address);

3. Log

  • 接收的包里有很多信息,我需要用到的就是通过正则表达式匹配提取IP:

Android 通过UDP广播建立Socket_第2张图片


三、调试工具

在电脑上测试了手机TCP/UDP报文的收发:

  • 设置Server端

    Android 通过UDP广播建立Socket_第3张图片

  • 手机发送UDP指令

    Android 通过UDP广播建立Socket_第4张图片

四、总结

在没有想到内置Wifi模块还有UDP功能前,还尝试过用ARP来解决问题。虽然最后选择了发UDP广播的捷径,但是解决问题的过程中学到的很多,可以参考另一篇博客Android 平台上的 ARP 和 ARP 欺骗。最后,谢谢在解决问题的过程中帮助过我的小伙伴们(✿◡‿◡)!

你可能感兴趣的:(Android)