网络服务器在 ESP32 上运行。 Android 应用程序是用 Java 编写的。 Android 手机和 ESP32 在同一个本地网络中。 最低 Android 版本是 Lollipop (5.0)。
查找本地网络中网络服务器的 IP (IPv4),以便通过向网络服务器发出 Http 请求(GET 和 POST)进行进一步通信。无法使用静态 IP,因此需要找到动态分配的 IP。
ESP32 支持 mDNS,但在 Android 上,仅从版本 12 开始支持。因此,从 Android 12 及以上版本使用 mDNS 没有任何问题。
因为 mDNS 无法在 Android 12 以下使用,目前的方法是获取手机的本地 IP(Ipv4),即 w.x.y.z,然后在 w.x.y.0 到 w.x.y.255 范围内循环,发出 Http 请求(超时设置为 500ms)对于每个请求)到每个 IP,通过比较响应来检查该 IP 是否是所需的 IP。这将永远如此;正在使用多线程,这显着减少了时间,但仍然太多(以秒为单位)。
对于 Android 12 以下的情况,这是比第二种方法更可靠、更快的解决方案。即使本地网络是通过路由器或同一 Android 手机的热点或通过某些不同手机的热点形成的,该解决方案也应该有效。
提前致谢。
PS:无法实现 DNS 服务器或类似的东西,因为 ESP32 正在消费产品中使用,并且根据消费者的 POV,数据应该可以从 Android 应用程序中的 ESP32 的网络服务器获得,而无需任何用户设置或配置。实际的解决方案代码不是必需的(如果您提供一个那就太好了),但也将赞赏如何解决此问题的逻辑或一般方法。
经过大量研究,我还提出了 UDP,正如@Robert 在评论中提到的那样,它工作得很好。这是代码,供有需要的人使用。
安卓(Java)
byte[] buffer = new byte[BYTE_SIZE];
try (DatagramSocket socket = new DatagramSocket(PORT)) {
socket.setSoTimeout(5000);
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String receivedIP = new String(packet.getData(), 0, packet.getLength());
// Rest of the code here to check if 'receivedIP' is desired one or not.
} catch (Exception e) {
e.printStackTrace();
}
ESP32代码
#include <WiFiUdp.h>
// Other includes
WiFiUDP udp;
void setup() {
// After connecting to LAN
udp.begin(PORT);
}
void loop() {
udp.beginPacket("255.255.255.255", PORT);
udp.print(WiFi.localIP());
udp.endPacket();
// Rest of the code
}